Skocz do zawartości

C++ Program do rozwiązywania równań kwadratowych


Recommended Posts

Jak zapewne przeczytaliście tytuł to zrobienie programu do rozwiązywania równań kwadratowych jest łatwe, lecz co jeśli chciałbym zrobić taki program, który rozwiązuje całe działanie np. 2x2 + 5x + 1 = 0. Do pewnego momentu sobie poradziłem, gdy liczby i zmienne wpisuje się w kolejności od największej potęgi do najmniejszej, czyli ax2 + bx + c = 0, ale problem pojawia się gdy wpiszę np. c + ax2 + bx = 0, a jak dobrze obliczyłem sposobów zapisu może być 18. Podam fragment kodu, w sposób jaki próbowałem tworzyć ten programik:)

 

#include<iostream>

using namespace std;

int main()
{
int a,b,c;// czyli liczba
char znak1,znak2; //czyli operator arytmetyczny
char potega;
char niewiadoma1, niewiadoma2;// czyli x

 

cin >> a >> niewiadoma1>> potega>> znak1>> b >> niewiadoma2 >> znak2 >> c;


 return 0;
}
 

Kto ma jakieś pomysły niech się nimi podzieli :)

Edytowane przez Kris16
Link to post
Share on other sites

Program nie zgadnie które liczby podaje użytkownik to raz (musisz to wymusić lub użytkownik musi określić którą z kolei podaje), a dwa gdzie masz dalszą część? :P Tutaj tylko wczytałeś liczby.

Dodatkowo:

Nie lepiej zrobić wczytywanie tylko a,b i c? Przecież x to jest bo jest i za niego się nic nie podstawia.

 

#include<iostream>
using namespace std;
int main()
{
int a,b,c; // czyli liczba
char zn1,zn2,x; //czyli operator arytmetyczny, x - tylko dla picu potrzebny
char st_p; //stopien potegi

cout<<"Wpisz rownanie"<<endl;
cin>>a>>x>>st_p>>zn1>>b>>x>>zn2>>c;
cout<<a<<x<<st_p<<zn1<<b<<x<<zn2<<c; //spr czy wszystko sie wczytuje jak chce

 return 0;
}
 

 

No i nie wiem skąd te 18, skoro 3 liczby (a,b,c) można ustawić na 3! (silnia) sposobów czyli 3*2*1=6.

Chociażby pierwsze zadanie stąd: http://zadane.pl/zadanie/4195230
 

Link to post
Share on other sites

Program nie zgadnie które liczby podaje użytkownik to raz, a dwa gdzie masz dalszą część? :P Tutaj tylko wczytałeś liczby.

Dodatkowo:

Nie lepiej zrobić wczytywanie tylko a,b i c? Przecież x to jest bo jest i za niego się nic nie podstawia.

 

#include<iostream>

using namespace std;

int main()

{

int a,b,c; // czyli liczba

char zn1,zn2,x; //czyli operator arytmetyczny, x - tylko dla picu potrzebny

char st_p; //stopien potegi

 

cout<<"Wpisz rownanie"<<endl;

cin>>a>>x>>st_p>>zn1>>b>>x>>zn2>>c;

cout<<a<<x<<st_p<<zn1<<b<<x<<zn2<<c; //spr czy wszystko sie wczytuje jak chce

 

 return 0;

}

 

Chyba wiem jak zrobić aby komputer rozróżnił w każdym momencie jakie będzie to równanie kwadratowe, lecz mam kolejny problem, ponieważ jak przed x nie będzie nic stało to komputer nie samodzielnie nie przejdzie do zmiennej char gdzie wpisuje się zmienna, lub operator. Trochę już zrobiłem tego programu i myślę że tak będzie dobrze działać, tylko jest problem z tym że jak nic nie będzie stało przed x :(

 

 

#include<iostream>


using namespace std;

int main()
{
int a; // Wprowadzamy zmienna
char opzm;   // Wprowadzamy operator(+,-,=) lub zmienna(x)
cin >> a;
cin >> opzm;

// Pierwszy warunek
if (opzm == '=')
{

    cout << "Rownanie 3\n";
    return 0;
}
// Koniec pierwszego warunku

// Wprowadzamy potege lub operator
char potega;
cin >> potega;

// Drugi warunek
if(potega == '2' )
{
    char operator1;
    cin >> operator1;

   if (operator1 != '=')
   {
     int a;
     char opzm;
     cin >> a;
     cin >> opzm;
     if (opzm == 'x')
     {
         char operator1;
         int a;
         cin >> operator1;
         cin >> a;

     }
     else
     {
       int a;
       char zmienna;
       cin >> a;
       cin >> zmienna;
     }



   }

   else
   {
      int a;
     char opzm;
     cin >> a;
     cin >> opzm;
     if (opzm == 'x')
     {
         char operator1;
         int a;
         cin >> operator1;
         cin >> a;

     }
     else
     {
       int a;
       char zmienna;
       cin >> a;
       cin >> zmienna;
     }

   }
   return 0;
}
// Koniec drugiego warunku

// Trzeci warunek
if (potega == '+' || potega == '-')
{
    cout << "Rownanie 2\n";
    return 0;
}
// Koniec trzeciego warunku


 return 0;
}
 
 
Edytowane przez Kris16
Link to post
Share on other sites

a ja bym ogólnie zaproponował zrobienie tablicy char'ów, do niej wpisać całą linijkę, a później przeprowadzać na niej testy, np:

jeśli na pozycji i jest '2' to jeśli na pozycji i-1 jest 'x' to a = wartość na pozycji i-2 [zamieniona na int oczywiście]

 

w sumie były by 3 fazy podstawowe:

- oznaczenie ax^2

- oznaczenie bx

- oznaczenie c

 

plus do tego oznaczenie działań + / - pomiędzy poszczególnymi pozycjami, które można ominąć np poprzez doczytanie jeszcze jednego argumentu podczas oznaczania [jesli na i-2 jest cyfra, to sprawdz i-3, jesli jest to cyfra to sprawdz i-4 ... jesli nie jest to cyfra, to zobacz jaki znak]

 

potem już z górki

Edytowane przez darasz89
Link to post
Share on other sites

Hej, ty chyba chcesz popełnić interpreter dla wyrażeń kwadratowych. :P Zadanie dość ambitne jak na zwykły program, który miał tylko liczyć równania kwadratowe.

Zwykle interpreter składa się z dwóch części: analizatora leksykalnego i analizatora składniowego. W twoim programie brakuje logicznego rozróżnienia dla tych pojęć i dlatego masz pewne problemy, jak np. "co się stanie jeśli nic nie będzie stało przed x", albo "co będzie jeśli wpiszę kilka spacji".

 

Gdybyś chciał to porządnie napisać, to w pierwszej kolejności powinieneś zacząć od zdefiniowania języka.

W Twoim języku (dla uproszczenia) można wyróżnić takie słowa kluczowe { -, +, x, x^2, =0}, oraz liczby całkowite (też dla uproszczenia). Następnie definiujesz gramatykę języka, czyli to jakie wyrażenia są poprawne. Na przykład wyrażenie x^2 - 1 = 0 jest poprawne (mimo, że nie ma członu "bx"), ale już x - 1 = 0 nie jest, jeśli zakładamy, że tylko równania kwadratowe są poprawne. Tutaj trzeba by rozrysować sobie przynajmniej drzewo składni, ale już nie chcę się zbytnio rozpisywać, więc odsyłam do http://pl.wikipedia.org/wiki/Analiza_sk%C5%82adniowa i tam podobnych, lub poczytaj sobie na googlach o "Technikach kompilacji".

 

-- 

analizator leksykalny (lexer) - zamienia wejściowy ciąg znaków na tokeny. Tokenami są w tym przypadku słowa kluczowe oraz liczby. Implementując taki lexer, można jednocześnie ignorować spacje i inne puste znaki. Można też dodać token terminalny, np. ";", wtedy równania trzeba będzie kończyć średnikiem. Funkcja analizatora zawsze powinna zwracać poprawnie rozpoznany token, lub kod błędu, jeżeli podano niepoprawny ciąg znaków, np. x^3 = 0.

 

analizator składniowy (parser) - karmiony tokenami z lexera, wykonuje analizę składniową, a więc sprawdza poprawność wyrażenia i wyróżnia podawane liczby przypisując do zmiennych: a, b, c. Po zakończeniu parsowania, będziemy wiedzieli, czy dane równanie jest poprawne pod względem składniowym,a jeśli tak, to zmienne a, b, c powinny zawierać poprawne wartości niezbędne do rozwiązania równania kwadratowego.

 

To tyle, tytułem wstępu. Teraz nie pozostaje nic innego, jak zabrać się za implementację. ;)

Edytowane przez nazgul1
  • Popieram 1
Link to post
Share on other sites
Gość Szczawson

Mysle ze autor tematu sam nie wie co pisze i nie wie co chce ostatecznie osiagnac ...  Z gory Ci napisze ze takie udziwniane zadanie sie zle zakonczy dla Ciebie bo nigdy tego nie zrobisz samemu. Prosty przyklad :

 

-5-5-4-3+x-2x+3x-4x+x^2-5*x^2=10*x^2-2*x^2+1+2+3+4+5+6

 

Have fun z parsowaniem jak masz podstawowe problemy z napisaniem zwyklego rozwiazywania.

Skad to wiem ? Widze po tym co do tej pory napisales, a raczej czego nie napisales. Sam styl kodu jest fatalny

 

Przyznaj sie ze chcesz zwykle rozwiazywanie rownania kwadratowego to Ci uwierze :)

Z reszta sam napisales pseudokomentarz : "//spr czy wszystko sie wczytuje jak chce".

No wlasnie co Ty wogole chcesz ? :hahaha:

 

Ostatecznie podsumuje tak : Jest to jedno z tych zadan ktore powinno sie zrobic samemu nawet jesli zaczynasz przygode z programowaniem. Dlatego tez uwazam ze pomoc w tym przypadku mozna pod warunkiem ze podstawowy program jest napisany a potrzebujesz "usprawnien". W innym wypadku nie ma mowy zeby cokolwiek Ci podpowiadac bo to sa absolutne podstawy ktore powinienes sam ogarnac lub nawet samemu poszukac.

 

Pozdrawiam

Edytowane przez Szczawson
Link to post
Share on other sites

napisanie obsługi "wyodrębniania" współczynników a,b,c z dowolnego zapisu porównującego do 0 to max 30 min

tak jak napisałem w poście wcześniej, wystarczą 3 funkcje - odpowiednio dla znalezienia a,b i c

w każdej z nich wystarczy jeden if dla rozpoznania i drugi dla wartości plus ewentualna funkcja / pętla dla liczb większych niż 9

 

@UP

zadanie tego typu zazwyczaj wygląda tak:

podaj a

podaj b

podaj c

wynik:

Edytowane przez darasz89
Link to post
Share on other sites

Mysle ze autor tematu sam nie wie co pisze i nie wie co chce ostatecznie osiagnac ...  Z gory Ci napisze ze takie udziwniane zadanie sie zle zakonczy dla Ciebie bo nigdy tego nie zrobisz samemu. Prosty przyklad :

 

-5-5-4-3+x-2x+3x-4x+x^2-5*x^2=10*x^2-2*x^2+1+2+3+4+5+6

 

Have fun z parsowaniem jak masz podstawowe problemy z napisaniem zwyklego rozwiazywania.

Skad to wiem ? Widze po tym co do tej pory napisales, a raczej czego nie napisales. Sam styl kodu jest fatalny

 

Przyznaj sie ze chcesz zwykle rozwiazywanie rownania kwadratowego to Ci uwierze :)

Z reszta sam napisales pseudokomentarz : "//spr czy wszystko sie wczytuje jak chce".

No wlasnie co Ty wogole chcesz ? :hahaha:

 

Ostatecznie podsumuje tak : Jest to jedno z tych zadan ktore powinno sie zrobic samemu nawet jesli zaczynasz przygode z programowaniem. Dlatego tez uwazam ze pomoc w tym przypadku mozna pod warunkiem ze podstawowy program jest napisany a potrzebujesz "usprawnien". W innym wypadku nie ma mowy zeby cokolwiek Ci podpowiadac bo to sa absolutne podstawy ktore powinienes sam ogarnac lub nawet samemu poszukac.

 

Pozdrawiam

 

 

Masz rację dopiero się uczę i może styl kodu jest fatalny. Może źle napisałem post mniejsza z tym. Nie chodzi mi o rozwiązywanie wyrażeń algebraicznym, ale o program który rozwiązuje równania kwadratowe. Nie ma tu nieskończoność warunków, a jak dobrze policzysz może być ich najwięcej 18 :)

Link to post
Share on other sites

1. ax2+bx+c=0

2. ax2+c+bx=0

3. ax2+bx=c

4. ax2+c=bx

5. ax2=bx+c

6. ax2=c+bx

7. bx+ax2+c=0

8. bx+c+ax2=0

9. bx+ax2=c

10. bx+c=ax2

11. bx=ax2+c

12. bx=c+ax2

13. c+ax2+bx=0

14. c+bx+ax2=0

15. c+ax2=bx

16. c+bx=ax2

17. c=ax2+bx

18. c=bx+ax2


Użyj cin.good() żeby wymusić sprawdzanie tego i jeśli nie będzie nic przez x niech wywali program.

Używaj tagów

 [ / code]

 

Dzięki Shaco wprowadziłem na początku programu zaraz po zmiennej "a" zapis cin.good(); oraz cin.clear(); i na razie działa :) Zobaczę co z tego wyjdzie jak dokończę ten programik :)

Link to post
Share on other sites

Kris Twoje rozumowanie jest dziwne bo i tak wszystko sprowadza sie do rownania w postaci :

 

a*x^2+b*x+c=0

 

i tego sie trzymaj

wczytuj po kolei wspolczynniki a,b,c

 

:)

Chodzi mi o to, że program ma rozróżnić wszystkie sposoby zapisu równania. Np ktoś wpisze 5x2 + 4x=1 to program musi 1 pomnożyć przez -1, czyli tak jak by przenieść tą jedynkę na drugą stronę aby otrzymać równanie ax2+bx+c. Nie chodzi mi o to żeby wpisywać same współczynniki, ale całe równanie wraz z x'ami

Edytowane przez Kris16
Link to post
Share on other sites

podzielić tablice [dla przejrzystości, można bez] poprzez znak '=', rozpoznać współczynniki, ustalić wartości przeciwne dla tych po '='

jak?

ustalić index w tabeli dla elementu '=', wszystkie wartości rozpoznane jeśli mają index większy niż '=' zmieniane są na przeciwne

oczywiście cały czas mam na myśli swój sposób - całą linijkę przekazać do tabeli char'ów i na niej operować

 

Np ktoś wpisze 5x2 + 4x=1 to program musi 1 pomnożyć przez -1

raczej odjąć 1

Edytowane przez darasz89
Link to post
Share on other sites

19. ax2+c=0

20. c=ax2

itd.

Zapomniałeś jeszcze o paru kombinacjach, ale przynajmniej teraz wiem dokładnie o co Ci chodzi. :P

Napisałem wcześniej prawidłowe podejście do twojego problemu, lecz dla początkującego programisty jak Ty, może to być zbyt trudne zadanie. Mimo to, nie chcę zabijać twojej radosnej twórczości, więc śmiało dalej kombinuj. W końcu zwykło się mówić, że istnieje tyle rozwiązań ilu programistów. :)

 

Podpowiem jeszcze tylko, że istnieje taka strategia jak "dziel i rządź", więc gdybyś podzielił swój program na kilka funkcji..., bo trzymanie wszystkiego w jednym main() jest, hmm... nieco hardcorowe. ;p

Edytowane przez nazgul1
Link to post
Share on other sites

raczej odjąć 1

 

W sensie programu to pomnożyć przez -1, czyli zmienić znak na przeciwny.

 

19. ax2+c=0

20. c=ax2

itd.

Zapomniałeś jeszcze o paru kombinacjach, ale przynajmniej teraz wiem dokładnie o co Ci chodzi. :P

Napisałem wcześniej prawidłowe podejście do twojego problemu, lecz dla początkującego programisty jak Ty, może to być zbyt trudne zadanie. Mimo to, nie chcę zabijać twojej radosnej twórczości, więc śmiało dalej kombinuj. W końcu zwykło się mówić, że istnieje tyle rozwiązań ilu programistów. :)

 

Podpowiem jeszcze tylko, że istnieje taka strategia jak "dziel i rządź", więc gdybyś podzielił swój program na kilka funkcji..., bo trzymanie wszystkiego w jednym main() jest, hmm... nieco hardcorowe. ;p

Widzę że jedna osoba wie o co chodzi. Innych przepraszam ponieważ trochę źle sprecyzowałem mój problem. No ale nazgul1 masz rację. Jestem początkującym programistą więc ciężko będzie mi zrobić taki program. Chyba że wiesz jak zrobić taką funkcję do której wpisujesz zmienną liczbową, a jeżeli jest to znak to pomija tą zmienną i zamiast niej wprowadza 1 :)Jeżeli taką funkcję udało by mi się zrobić to program by działał dobrze moim sposobem :)

Edytowane przez Kris16
Link to post
Share on other sites

uwierz mi żadnych zaawansowanych technik tutaj nie ma - same funkcje znajdywania mają kilka linijek i zawierają 1 for i 2 if'y ;)

wszystko jest uproszczone, bo korzystasz z tablicy znaków, po której można się swobodnie przemieszczać

także skoro jesteś początkujący, to rób proste rzeczy, baw się właśnie tablicami, wskaźnikami, operacjami na tablicach, itp itd

to co Ty chcesz faktycznie wystaje już trochę poza "początkującego", także poćwicz i wróć do tego później :P

Edytowane przez darasz89
Link to post
Share on other sites

uwierz mi żadnych zaawansowanych technik tutaj nie ma - same funkcje znajdywania mają kilka linijek i zawierają 1 for i 2 if'y ;)

wszystko jest uproszczone, bo korzystasz z tablicy znaków, po której można się swobodnie przemieszczać

także skoro jesteś początkujący, to rób proste rzeczy, baw się właśnie tablicami, wskaźnikami, operacjami na tablicach, itp itd

to co Ty chcesz faktycznie wystaje już trochę poza "początkującego", także poćwicz i wróć do tego później :P

 

No cóż pozostaje mi dalej poznawać język c++

Link to post
Share on other sites

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Odpowiedz w tym wątku...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...