Kalkulacka v c++ (s roznym vstupom)

Programovacie jazyky, rady, poradňa...
Oblak
Light Expert
Light Expert
Príspevky: 60
Registrovaný: 27 máj 2015, 15:40

Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Oblak »

Zaujímalo by ma, či naprogramovanie kalkulačky s takýmto vstupom do konzolového riadku

Kód: Vybrať všetko

((3*2)-(2*2))/2 =
 a vypočíta výsledok
je ťažké pre začiatočníka? A všeobecne je to ťažké alebo ľahké?

Ako by ste riešili takúto vec vy (bez použití knižníc okrem iostream), keby ste ju mali naprogramovať?

Našiel som ešte jednu tému, kde sa rieši tá istá otázka
prevod-retazca-2-2-2-na-matematicku-fun ... kalkulacka
je tam odpoveď od Harrisona, ktorý zrejme dáva tipy na algoritmy a použitie nejakej knižnice, ja by som to chcel použiť bez žiadnej knižnice a dajme tomu, že s vlastným riešením - teda nepozerať po hotových algoritmoch.
xadman
Medium Star
Medium Star
Príspevky: 305
Registrovaný: 09 mar 2011, 17:02

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa xadman »

Henten vstup treba vyparsovať a buď pomocou stacku, alebo binárneho stromu to vieš vypočítať.
BX
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4572
Registrovaný: 10 jan 2008, 15:30

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa BX »

Oblak napísal:je ťažké pre začiatočníka?
No... nie je to ľahké.
Oblak napísal:A všeobecne je to ťažké alebo ľahké?
Také stredné. Nejaké znalosti na to už treba, ale zase každý vzdelaný programátor by to mal vedieť.

Rieši sa to rekurzívnym zostupom (rekurziou, alebo explicitným stackom). Hľadaj math expression parsing, alebo všeobecnejšie bezkontextové gramatiky.

//Shunting yard mi veru vypadol :oops: Ďakujem za doplnenie.
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8216
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa harrison314 »

Vo vseobecnosti sa to da resit tym co ti poradil BX, ale a takyto konkretny pripad, ked tam nie su premenne, cykli ani nejake zlozitejsie syntakticke veci, staci nieco ovela jednoduchsie (odpada syntakticka analza)
Dijikstrov Shunting yard algoritmus
Oblak
Light Expert
Light Expert
Príspevky: 60
Registrovaný: 27 máj 2015, 15:40

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Oblak »

Vďaka.

Tak ak sa nenahneváte, ja už som to naprogramoval :). Len som si chcel overiť, či je to hodné prezentovať sa s tým ako začiatočník. Ja som nevyužil rekurziu ani stack. Použil som vlastnú metódu, teda nehľadal som po nete ako čo spraviť. Ale ešte predtým som si čítal niečo o algoritmoch takže niečím som sa predsa len inšpiroval.

Taktiež by ma ešte zaujímalo ako by ste to riešili viac dopodrobna, pretože toto boli podľa mňa, veľmi všeobecné informácie. Vaše odpovede znejú ako keby sa to dalo napísať na niekoľko riadkov (príde mi to takto = použijem to a to, a je to). Ja mám napr. cez 500 riadkov, ale je možné písať chyby a tie chyby bude ignorovať ako napr.

Kód: Vybrať všetko

2 + 2 ) * ( * 2 + 2 * 3* ( 2 - 1 ) =
toto vypočíta ako
(2+2) * (2+2*3*(2-1))
Jedine čo som nespravil je ošetrenie takejto veci

Kód: Vybrať všetko

(2+2) * (-2+2)
to mínus pred dvojkou bude ignorovať. Dorobím to neskôr, momentálne som rád že sa mi podarilo počítať so zátvorkami.

Prikladám aj program, len neviem, či ho spustíte. Mne ide, ale keď som ho spustil na inom notebooku s WinXP tak vypísalo chybu, že to nie je platná win32 aplikácia. Kompiloval som to na Win7, možno preto.
PS: skúsil som nejaký ešte jeden build, tak neviem, netestoval som ho na inom notebooku. Snáď vám bude fungovať.
Prílohy
Kalkulacka 3.rar
(6.99 KiB) 104 stiahnutí
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8216
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa harrison314 »

Toto je jednoducha a taka skor akademiska vec, takze ak si to spravil spravne, tak tvoje rienie bude velmi podobne nejakemu existujucemu.

Inak, prezentovat execkom sa sice mozes, ale to nic nepovie o tom aky si programator. Radcej ukaz zdrojaky.
Oblak
Light Expert
Light Expert
Príspevky: 60
Registrovaný: 27 máj 2015, 15:40

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Oblak »

Ok, ak sa vám v tom bude chcieť hrabať, budem rád za kritiku. Len upozorňuje, že tam nie je upratané, tak môžte naraziť na nič nerobiacu funkciu. Je tam tuším jedna taká.
*****HERO*****
Guru wannabe
Guru wannabe
Používateľov profilový obrázok
Príspevky: 2446
Registrovaný: 08 máj 2006, 1:34

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa *****HERO***** »

toto si napisal za 3 hodiny (od zalozenia temy) ??
Oblak
Light Expert
Light Expert
Príspevky: 60
Registrovaný: 27 máj 2015, 15:40

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Oblak »

Nie, písal som to omnoho dlhšie. Keď som založil diskusiu už som to mal napísane. Dokopy som to písal niekoľko dní, myslím že skoro týždeň. Ale vždy som sa nejak zasekol, lebo kód bol veľmi zložitý a napadli ma nové veci, ako by sa to dalo riešiť jednoduchšie. Tak som to vždy robil od začiatku. Túto poslednú tretiu verziu som robil asi tri dni. Samozrejme nie v kuse. Raz som nad tým presedel skoro celý deň ak som mal čas, inokedy som tomu venoval pár hodín. Deň prestávka a tak podobne.
BX
Addict
Addict
Používateľov profilový obrázok
Príspevky: 4572
Registrovaný: 10 jan 2008, 15:30

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa BX »

Keď ešte fungoval audiotrack.hojko.com (pozdejší zdrojak.sk), tak tam bola na toto úloha. A mňa samozrejme nenapadlo iné riešenie, než si tiež takýto program napísať. Napísal som tiež pár stoviek riadkov v php, neviem už ani ako, ale fungovalo to. Teda ak bol výsledok menší, než 10tisíc a vnorenie nebolo nejaké zložité :D Celé riešenie stálo na tom, že správny výsledok to dalo len pre jednoduchšie prípady a tak som správne riešenie odovzdal na nejaký Xtý pokus.

Potom som mal takýto program ako semestrálku v druhom semestri na univerzite. To už som použil rekurziu, ale parsing som nepoznal. A shunting yard sa mi nepáčil. Tiež z toho bolo pár stoviek kódu v C++, ale už aj sada rekurzívnych funkcií, ktoré sa trochu blížili efektívnemu riešeniu.

No a potom prišili automaty a gramatiky a parsing. A rovnaký program, ako som napísal už dva krát v stovkách riadkov a za dlhé hodiny, som v obyčajnom C-čku napísal za hoďku ako nič.

Toť spoveď z dlhej púte programátora. Vzdelanie a vedomosti nadovšetko :)
lowmanek
Light Professional
Light Professional
Používateľov profilový obrázok
Príspevky: 977
Registrovaný: 04 apr 2010, 8:53
Bydlisko: 221B Baker Street

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa lowmanek »

V knihe Algoritmy a programovací techniky je super kapitola o vyhodnocovaní výrazov a prefixovej notácii. Je tam aj kód v Pascale - okolo 50 riadkov ak si dobre pamätám.
Celkovo túto knihu veľmi odporúčam - aspoň základy teoretickej informatiky by mal mať podľa mňa každý programátor ;)
Oblak
Light Expert
Light Expert
Príspevky: 60
Registrovaný: 27 máj 2015, 15:40

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Oblak »

lowmanek: vďaka za tip

Prečítal som si ten shunting yard algoritmus čo poslal odkaz harrison a myslím si, že niečo podobné mám aj ja a podľa mňa je to asi zatiaľ (pre mňa) najprirodzenejšie riešenie.

Ja pracujem s poľami, kde v 1. poli ukladám znamienka ako +-*/, 2. kde ukladám kde sa nachádzajú číslice a znaky, 3, pole ktoré znázorňuje zátvorky a do 4. poľa ukladám čísla. Posledné 5. pole je pre konverziu vstupu čísla do číselného poľa. (To pole na ukladanie znakov +-*/ byť nemuselo, keďže mám pole na čísla a znaky, ale to ma napadlo neskôr a prepisovať sa mi to už nechcelo)
Na rozdiel od shunting yard algoritmu ja to nedávam do zásobníka, ale dám vyhľadať zátvorku (tú najhlbšiu vloženú ak nejaká je). Potom dám vyhľadať znamienka ako +-*/ a podľa priority vypočítať v danej zátvorke, ak nejaká je. Potom sa zátvorka zruší. No a takto sa to opakuje. Možno je to zložité, ale na predstavu je mi to viac zrozumiteľnejšie ako iné techniky. Ale ten shunting yard algoritmus sa mi pozdáva, inokedy si ho skúsim napísať.
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8216
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa harrison314 »

Oblak napísal:Ja pracujem s poľami, kde v 1. poli ukladám znamienka ako +-*/, 2. kde ukladám kde sa nachádzajú číslice a znaky, 3, pole ktoré znázorňuje zátvorky a do 4. poľa ukladám čísla. Posledné 5. pole je pre konverziu vstupu čísla do číselného poľa. (To pole na ukladanie znakov +-*/ byť nemuselo, keďže mám pole na čísla a znaky, ale to ma napadlo neskôr a prepisovať sa mi to už nechcelo)
Na rozdiel od shunting yard algoritmu ja to nedávam do zásobníka, ale dám vyhľadať zátvorku (tú najhlbšiu vloženú ak nejaká je). Potom dám vyhľadať znamienka ako +-*/ a podľa priority vypočítať v danej zátvorke, ak nejaká je. Potom sa zátvorka zruší. No a takto sa to opakuje. Možno je to zložité, ale na predstavu je mi to viac zrozumiteľnejšie ako iné techniky. Ale ten shunting yard algoritmus sa mi pozdáva, inokedy si ho skúsim napísať.
Ja som daco podobnerobil po prvom semestri v C (fungovalo to na rovnakom principe ako to tvoje), prosto rovnaky postup, este niekde tu na hojkovi mam o tom temu.
Potom prisiel shunting yield algoritmus a obycajne vyhodnocovanie vyrazu uz nebolo zaujimave, tak som to okorenil o to, ze moja "kalkulacka" vedela derivovat vyrazy podla x, paradoxne naprogramovat to (vtedy este v PHP) bolo lahsie ako derivovat rucne.
Alebo som robil prekladac Abacus machine do vlastneho bytecodu, a k tomu som spravil interpreter, ale to tiez rekurziou.
Potom som presiel na generatory syntaktickych a lexikalnych parserov a cela ta magia sa zmenila na zapis gramatiky, na cca 10-20 riadkov.
Nakoniec prisiel predmet Prekladace, kde v C++ bolo treba nakodit lexikalny aj syntakticky analzator nejakeho skutocneho jazyka, k prekladu do nejakeho pseudoasembleru je odtial len krok.

takze myslim, ze takymto obdobim si prejde kazdy :D

//autoeditácia príspevku (13 Apr 2016, 14:00)
Pre Karmistu:
Preco som to robil v PHP ? lebo som si to chcel dat na svoju prezentacnu stranku :D nad inym som v tomto pripade ani neuvazoval. Nebol za tym nejaky iny dovod.
Blackout147
Medium Expert
Medium Expert
Príspevky: 124
Registrovaný: 19 jún 2012, 17:22
Bydlisko: Bratislava

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Blackout147 »

Akurat som to pred tyzdnom robil aj ja. Ucim sa programovat nieco menej cez mesiac, tak berte na to ohlad :D

Funguje to v principe tak ako to Oblak opisal, len ja tam mam 2 polia - 1. pre znamienka, druhe pre cisla. Zatvorky mam riesenie ako substring, ktory program vypocita a vysledok vrati namiesto zatvorkoveho vyrazu. K objektom a OOP sa dostavam len teraz, takze to bol prvy pokus o class.

Program je ale v C#.
Prílohy
KalkulackaSTRING.rar
(41.1 KiB) 99 stiahnutí
harrison314
Hardcore addict
Hardcore addict
Používateľov profilový obrázok
Príspevky: 8216
Registrovaný: 27 máj 2009, 20:42
Bydlisko: Bratislava
Kontaktovať používateľa:

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa harrison314 »

@Blackout147: zapemataj si ze goto je zakazana temna magia, nepouzivaj ho inak...
Prílohy
0baa1b9fae6aec55bbb73037f3016001-xkcd-goto.png
Blackout147
Medium Expert
Medium Expert
Príspevky: 124
Registrovaný: 19 jún 2012, 17:22
Bydlisko: Bratislava

Re: Kalkulacka v c++ (s roznym vstupom)

Príspevok od používateľa Blackout147 »

Hej, uz mi bolo povedane. Namiesto goto tam staci dat i = 0, len ked som to pisal mi nenapadlo.
Napísať odpoveď