[Delphi] Wyra?żenia matematyczne

0

Mam problem... Potrzebuje program, który oblicza wartość wyrażenia matematycznego w stringu (np.: 1,98*(12+4) ).Probowalem taki [glowa] napisać, ale podaje głupie wyniki w niektórych przypadkach.
Prosiłbym o podesłanie wyżej opisanego programu [email protected]
Z góry thx.

0

[niewinnosc]

Prosiłbym o podesłanie wyżej opisanego programu [email protected]

He he.

Nie wiem czy zdajesz sobie sprawę z tego, że napisanie takiego programu to kawał roboty. Prawdę mówiąc, nie sądzę żeby ktokolwiek napisał go dla Ciebie za darmo.

Możliwe są dwa podejścia:

  1. Przeładowanie operatorów. ( Dostępne w C++ ) Każdy średnio-zaawansowany programista powinien sobie poradzić z napisaniem takiego programu korzystając z przeładowania operatorów arytmetycznych względem zmiennych typu String. ( Obecność tego mechanizmu jest prawdopodobnie największą siłą C++ )

  2. Zdefiniowanie operacji arytmetycznych, określenie ich priorytetów, napisanie interpretatora i odkładanie coraz to prostszych wyrażeń na stos (tzw. "Dziel i zwyciężaj), całość rekurencyjna (jest to po prostu najbardziej naturalna i czytelna obsługa LIFO, czyli "last in first out"), oczywiście dochodzą do tego zagadnienia dynamicznego przydziału pamięci, (bo przecież nie wiemy z góry, na ile członów rozpada się wyrażenie). Już jest źle ? Będzie gorzej - obecność nawiasów komplikuje to wszystko, gdyż z punktu widzenia interpretatora wymagają one osobnego potraktowania.

Mam nadzieję że odrobinę przybliżyłem Tobie złożoność tego pozornie niewinnego problemu.

Pozdrawiam.

0

Mam nadzieję że odrobinę przybliżyłem Tobie złożoność tego pozornie niewinnego problemu.

Tym niemniej kiedys na forum ktos sie kiedys chwalil, ze napisal taki program. Nie pamietam kto, no i program pewnie byl jakos ograniczony, po problem na pewno nie jest banalny.

--
Pawel {Delphi 6 Personal}

Po pierwsze: naciśnij F1

0

Hej pq ! :-)

W odpowiedzi na twojego posta mogę powiedzieć że to bardzo prawdopodobne.

Chciałem jedynie pokazać, że nie istnieje coś takiego jak prosta konwersja wyrażenia zapisanego w formie literału na wyrażenie w formie arytmetycznej.

Niemniej napisanie takiego programu nie jest niemożliwe. W gruncie rzeczy implementacja sprowadza się to do rozpisania rekurencyjnie zagnieżdżonego Interpretatora. (gdybyśmy użyli rekurencji to prawdopodobnie za cenę szybkości programu odpada problem dynamicznego przydzielania pamięci, a nie jest to wygórowana cena za taki towar )

Naprawdę da się to zrobić, aczkolwiek wymaga to trochę pracy. (chyba że piszemy w C++, wtedy można to zrobić w jakieś 40 minut).

Pozdrawiam.

0

Jak się nie mylę to w przykładach tu na stronie jest zrobione proste dodawanie!. Ja napisałem interpreter, pozwalający w postaci łancucha wprowadzić strukturę elektrycznej sieci zastępczej (ileśtam rezystorów, kondensatorów itp w połączeniach równoległych i szeregowych) procedura była rekurencyjna i zajmowała ze 50 lini, ale czas na debugi to około 2 tygodni dobrego gmerania i tropienia wyjątków.

0

He he.

Nie wiem czy zdajesz sobie sprawę z tego, że napisanie takiego programu to kawał roboty. Prawdę mówiąc, nie sądzę żeby ktokolwiek napisał go dla Ciebie za darmo.

I tu się mylisz. Prosty kalkulator umożliwiający operacje:
+, -, *, / przedstawił już tutaj (chyba) Sheitar i RFL.

Ja też brałem się za takie coś (fragmenty ich kodu dot. operacji na nawiasach ściągnąłem) i napisałem sobie prosty kalkulator obsługujący:
+, -, *, /, mod, div, not, and, or, xor i ^ (potęgowanie).
Oprócz tego próbowałe rozszerzyć o kilka predefinowanych funkcji (sin i cos). Niestety ta ostatnia operacja doprowadziła do pewnych problemów, które występowały w kalkulatorze RFLa, a ja usunąłem (np. podwójny '-' czy wielokrotne znaki białe). Nie kończyłem tego, bo właśnie dorwałem się do kompilatorów i tu mam bardzo ciekawe algorytmy. Zamierzam umieścić tu artykuł na ten temat, więc Paweł, jezeli nie potrzebujesz tego na gwałt, to poczekaj kilka dni (do niedzieli), a umieszczę tu artykuł wraz z kodem (jeżeli potrzebujesz natychmiast to mogę przesłać ten wcześniejszy kalkulatorek - jak tylko wrócę do stanu działającego, czyli bez funkcji).

  1. Przeładowanie operatorów. ( Dostępne w C++ ) Każdy średnio-zaawansowany programista powinien sobie poradzić z napisaniem takiego programu korzystając z przeładowania operatorów arytmetycznych względem zmiennych typu String. ( Obecność tego mechanizmu jest prawdopodobnie największą siłą C++ )

W Delphi przeładowanie operatorów występuje tylko w typie Variant. Ale tu męczenie się z przeładowaniem operatorów to zbędna robota.

  1. Zdefiniowanie operacji arytmetycznych, określenie ich priorytetów, napisanie interpretatora i odkładanie coraz to prostszych wyrażeń na stos (tzw. "Dziel i zwyciężaj), całość rekurencyjna (jest to po prostu najbardziej naturalna i czytelna obsługa LIFO, czyli "last in first out"), oczywiście dochodzą do tego zagadnienia dynamicznego przydziału pamięci, (bo przecież nie wiemy z góry, na ile członów rozpada się wyrażenie). Już jest źle ? Będzie gorzej - obecność nawiasów komplikuje to wszystko, gdyż z punktu widzenia interpretatora wymagają one osobnego potraktowania.

Zgadza się, rekurencyjna metoda jest najłatwiejsza. Ale pomysł wprowadzony przez Sheitara i RFLa w sprytny sposób pozbywa się konieczności używania stosu i usuwa praktycznie wszystkie problemy z nawiasami. (a tak przy okazji można to też zrobić w wersji iteracyjnej - znacznie szybszej i odporniejszej na sporo błędów)

Mam nadzieję że odrobinę przybliżyłem Tobie złożoność tego pozornie niewinnego problemu.

Nie taki złożony, jeżeli to mają być proste wyrażenia matamatyczne :)

--
Jest jeszcze jeden błąd ... :)
--------Oficjalny kanał----------
Service for programmers w IRC:
Kanał: #4programmers
Serwer: warszawa.ircnet.pl
Sieć: POLNet
Port: 6667

0

Thx za probe pomocy, ale rozwiazalem problem :) (w niecały tydzień) Chociaz troszke wolny, ale wystarczający...

0

Stos i odwrotna notacja.

Jak to zrobiłeś, to jestem ciekaw czy to obliczy:
-(-(((1)-)), chodzi mi czy sprawdza zgodność nawiasów?

--
Carl Friedrich Gauss(1777-1855) - Niemiec, książe matematyków

0

Stos i odwrotna notacja.
Jak to zrobiłeś, to jestem ciekaw czy to obliczy:
-(-(((1)-)), chodzi mi czy sprawdza zgodność nawiasów?

U mnie wywal błąd przy nieodpowiedniej ilości nawiasów odtwierających i zamykających (czyli tak jak być powinno). Tego nie przepuściłoby nawet z tego powodu, że po '-' brakuje wyrażenia.
A tak w ogóle to ja bym tego nie robił na stos, ale na kolejkę (taki mały szczegół).
Odwrotna notacja? Odwrotna notacja to jest notacja Łukasiewicza (polish notation). Tutaj przydałoby się raczej stosować notację postfixową.
2+34 -> 234+

--
Jest jeszcze jeden błąd ... :)
--------Oficjalny kanał----------
Service for programmers w IRC:
Kanał: #4programmers
Serwer: warszawa.ircnet.pl
Sieć: POLNet
Port: 6667

0

A swoją drogą to jestem NIEZMIERNIE ciekaw jak rozwiazales ten problem panie Pawel200x.5.
Chcialem kiedys napisac program do rysowania wykresow funkcji, ale nie napisalem. Powalil mnie wlasnie ten problem co u Ciebie.
Jak bys byl na tyle mily to wyslij tu na forum ten kod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1