Strings berechnen (Auch "Eval" genannt)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Little John

Beitrag von Little John »

AND51 hat geschrieben:> Top-Down-Ansatz
Das ist also die Methode, wenn man innerste Klammern zuerst berechnet und dieses Teilergebnis rekursiv zurü+ckgibt, bis man "unten", also auf äußerster Ebene angekommen ist?
Wenn ja, fände ich das auf Anhieb einfach, es so zu probieren.
Top-Down-Methoden bestimmen zuerst Teile des zu berechnenden Ausdrucks, dann Teile von Teilen usw., bis die Teile klein genug sind um direkt ausgewertet zu werden. Bottom-up-Methoden nehmen kleine Teile der Eingabbedaten und setzen sie in strukturierter Weise so zusammen, dass immer größere Teilstücke entstehen, bis schließlich der ganze Ausdruck ausgewertet ist. Für mehr Informationen google einfach mal nach "Syntaxanalyse" oder "Parser".

Ja, der rekursive Top-Down-Ansatz leuchtet vielen Leuten spontan intuitiv ein -- zumindest Leuten denen rekursives Denken nicht fremd ist.
AND51 hat geschrieben:> Bottom-Up-Ansatz
Und das ist meine 2. Idee, alles in ein Array zu separieren?
Hier habe ich mal mit Regulären Ausdrücken versucht, einen Teststring zu separieren.
Bis jetzt separiert er nur Zahlen und Nicht-Zahlen. Nicht-Zahlen sind also Mathematische Operatoren.

So meinst du das doch, oder?
Nee, hier verwechselst Du jetzt glaub ich was. "Separieren" muss man die Sachen ja sowieso. In jedem Fall.
Ein String besteht ja zunächst einmal nur aus "aneinandergehängten" Zeichen. Der String muss in einzelne Token separiert werden, dazu hatte ich auch schon was geschrieben. Der Programmteil der das macht nennt sich "Scanner". Wie der Scanner die einzelnen Token separiert, ob mit RegEx oder anders, finde ich eigentlich gar nicht so wichtig ;) (Kann aber natürlich Geschwindigkeitsunterschiede mit sich bringen.) Bei diesem Code extrahiert die Procedure GetToken() immer einen neuen Token aus dem Quellstring in dem Moment, wo der Token gebraucht wird.
Wenn Du als erstes den Quellstring in Token aufteilst (ob mit RegEx oder ohne) und die einzelnen Token in einem Array abspeicherst, dann müssen die Token eben anschließend aus dem Array gelesen werden. Das ändert am Prinzip des Programms gar nichts! Mein Code lässt sich leicht dahin gehend abwandeln, und es bleibt ein rekursiv absteigender Parser, egal ob man die Token quasi "ad hoc" aus dem Quellstring separiert, oder alle Token am Anfang separiert und irgendwo zwischenspeichert, und dann später nach und nach aus dem Zwischenspeicher holt.

edit 27.7.2008
Eine so abgewandelte Version meines Codes findet sich jetzt hier. Ich denke sie eignet sich gut für Experimente mit RegEx o.Ä.

Gruß, Little John
Zuletzt geändert von Little John am 27.07.2008 17:21, insgesamt 1-mal geändert.
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

@LittleJohn

Findest es nicht etwas krass, dass du bei Division durch Null gleich das gesamte Programm beendest :shock:

Code: Alles auswählen

   If r = 0 
            Debug "Error: Division by zero." 
            End 
         EndIf 
Stellt euch das mal bei Windows vor. Wenn das ausgehen würde, wenn einer versucht durch Null zu teilen :D :allright:

Mir ist gerade aufgefallen, dass deine gesamte Fehlerabarbeitung gleich aus dem Programm geht. Ohne dir zu nahe zu treten, aber wie sinnvoll ist das denn?

Wenn ich im Debug-Modus eh nur die Fehlermeldungen sehen kann, kann ich auch gleich schreiben:

Debug 100.4+56*(456-45*(4-1)+34)-5

Aber du hattest ja geschrieben, dass du den Code kurz halten willst und es nur eine Portierung war.
Ich glaube, ich würde wieder einen String ausgeben.

ValF(Calc("..."))

Wäre dann zwar nötig, aber so könnte man die Fehlerbehandlung dennoch machen.

:roll:
Kinder an die Macht http://scratch.mit.edu/
Little John

Beitrag von Little John »

Der Code hat tatsächlich nur eine rudimentäre Fehlerbehandlung. Mein Ziel war es hauptsächlich, zu dem Zeitpunkt das Prinzip eines rekursiv absteigenden Parsers zu verdeutlichen. Da hatte ich nicht mehr fertig. Jetzt arbeite ich gaaanz in Ruhe an einer erweiterten Version. :D

Gruß, Little John
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Strings berechnen (Auch "Eval" genannt)

Beitrag von STARGÅTE »

Sry das ich das Thema wieder ausgrabe, aber der Code vorne ist immer noch voller Fehler:

Code: Alles auswählen

Debug CalcStr("5-2-1")
Hier wird 4 ausgegeben.
Vermutlich weil auf Grund des Auslesens erst 5-? gemacht wird, dann geht er weiter und rechnet 2-1 aus was 1 ist welches dnan ins ? kommt aber er müsse ja erst 5-2 normal rechnen und dann noch mal -1 ...

selbes Problem hier:

Code: Alles auswählen

Debug CalcStr("5-3+2")
Hier wird 0 ausgegeben, obwohl es 4 ist!

Oder hier:

Code: Alles auswählen

Debug CalcStr("40/4/2")
Hier wird 20 ausgegeben, statt 5
weil die procedure wieder erst 40/? im Kopf hat und ? dann 4/2 = 2 ist und dann 40/2=20 aber auch hier muss die Reihenfolge beachtet werden: also erst 40/4 = 10 und dann 10/2 = 5 ...

Die Reihenfolge (von Vorne nach Hinten oder Hinten nach Vorne) wie man zB 1+2+3+4 errechnen lässt oder 1*2*3*4 mag ja egal sein, aber bei - oder / muss die Reihenfolge beachtet werden, was hier nicht geschied.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Josef Sniatecki
Beiträge: 657
Registriert: 02.06.2008 21:29
Kontaktdaten:

Re: Strings berechnen (Auch "Eval" genannt)

Beitrag von Josef Sniatecki »

Hi, der Code ist wirklich felerhaft. Bin aber jetzt wirklich nicht dazu motiviert, diesen jetzt noch zu korrigieren :mrgreen:.
Ich selbst verwende seit einiger Zeit meine eigene Programmiersprache als Parser: http://www.purebasic.fr/german/viewtopi ... 10&t=20531
Hinweis: Die Befehle zum Auswerten heißen nun "OpernoEvalI", "OpernoEvalF" usw.

Gruß Josef
PB 4.61 | Windows Vista - 32Bit
Homepage

"Wahrlich es ist nicht das Wissen, sondern das Lernen, nicht das Besitzen sondern das Erwerben, nicht das Dasein, sondern das Hinkommen, was den grössten Genuss gewährt." - Carl Friedrich Gauß
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Strings berechnen (Auch "Eval" genannt)

Beitrag von Kiffi »

Code: Alles auswählen

UseSQLiteDatabase()
OpenDatabase(0, ":memory:", "", "", #PB_Database_SQLite)
DatabaseQuery(0, "Select 40/4/2")
NextDatabaseRow(0)
Debug GetDatabaseString(0, 0)
CloseDatabase(0)
8)

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Sauer-RAM
Beiträge: 326
Registriert: 13.04.2009 16:22
Computerausstattung: Lenovo ThinkPad X230t Convertible
Wohnort: Haslach i. K.

Re: Strings berechnen (Auch "Eval" genannt)

Beitrag von Sauer-RAM »

Mann genau sowas hab ich vor kurzem mal gesucht und mir ewig überlegt, wie ich das am besten mache. >_<

Und für die leute sie jetzt noch den Grund wissen wollen: Weil ich eine eigene kleine Eingabeaufforderung programmieren wollte und da gehört rechnen einfach dazu.
"Bildung kommt vom Bildschirm und nicht vom Buch, sonst hieße es ja Buchung."
Dieter Hildebrandt
"Bildung ist Das, was übrig bleibt, wenn man alles was man in der Schule gelernt hat, vergisst. "
Albert Einstein
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Strings berechnen (Auch "Eval" genannt)

Beitrag von STARGÅTE »

@Kiffi

Sowas nennt man bei uns CHEATER !!

Aber :allright: , Super idee n Datenbank dafür zu missbrauchen :lol:
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
marco2007
Beiträge: 906
Registriert: 26.10.2006 13:19
Kontaktdaten:

Re: Strings berechnen (Auch "Eval" genannt)

Beitrag von marco2007 »

@Kiffi: Genial :allright:
Windows 11 - PB 6.03 x64
_________________________________
Antworten