Einzelnen Beitrag anzeigen

Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#12

Re: Welche Methode zum Parsen von chemischen Formeln?

  Alt 27. Apr 2007, 10:52
Benutze den Debugger und schaue dir die Variablen im Watch-Window an.

Das Programm gliedert sich Prinzipiell in zwei Teile (genauso, wie man es auch beim ausführen sieht)

1. Teil: Einsetzen von Operationszeichen
Das Ergebnis wird in dem, von oben gesehen, zweiten Edit-Feld angezeigt (was edit3 heißt).
Aus z.B. H2O wird H*2+O. Bzw. aus 3H3S04 wird 3*(H*3+S+O*4).
Das alles erledigt die Funktion "zeichensetzen" (mit Hilfe von "PlusvorZahl")
Die Funktion geht einfach Schritt für Schritt durch den String "term" und schaut z.b sowas an:
Delphi-Quellcode:
//...
else if (term[k] in ['a'..'z','A'..'Z'])and(term[k+1] in ['0'..'9']) then
      term:=copy(term,1,k)+'*'+copy(term,k+1,length(term))
//...
{Wenn an Stelle k im term ein Buchstabe ist und an Stelle k+1 im term eine Zahl, dann wird dazwischen ein '*' gesetzt
für k=1 und term='H20' wird so term:='H'+'*'+'2O'
Wenn nix geändert wird erhöht sich k um 1 ansosnten um 2. Demnach ist jetzt k=3 (da was geändert wurde)
Beim nächsten Schleifendurchlauf dürfte die Funktion anfolgender Bedingung hängen bleiben:}

if (term[k] in ['0'..'9'])and(term[k+1] in ['a'..'z','A'..'Z']) then
    begin
      if PlusvorZahl(term,k) then begin
        n:=k+1;
        //Klammer setzen: 2H2SO4+2Cl --> 2*(H*2+S+O*4)+2*(Cl)
        while (n<=length(term))and not(term[n] in ['(',')','+']) do inc(n);
        term:=copy(term,1,k)+'*('+copy(term,k+1,n-k-1)+')'+copy(term,n,length(term));
        inc(k);
      end else
        term:=copy(term,1,k)+'+'+copy(term,k+1,length(term));
    end
{term[k] ist eine Zahl und term[k+1] ein Buchstabe
Hier muss erstmal überprüft werden, was vor der Zahl passiert ist, deswegen die Funktion PlusvorZahl. wenn vor der Zahl (hier: 2) ein Pluszeichen steht (oder der Term vor der Zahl anfängt), dann muss eine Klammer gesetzt werden (inkl. Multiplikationszeichen)
ansonsten kommt ein Pluszeichen hinter die Zahl
z.B. in 3H2O existiert zweimal der Zustand: erst Zahl dann Buchstabe "3H" und "2O" aber aus "3H" wird "3*(H"...")" und aus "2O" wird einfach "2+O", da die zwei ja zum Wasserstoff gehört.}
Soviel zur Funktion "Zeichensetzen". Das Ergebnis wird wie bereits erwähnt auch im Programm angezeigt.
Bis hierhin war es neu. Ab jetzt braucht man die Formel (den Term), die man erstellt hat nur noch auszurechnen und für die chemischen Zeichen, die wir jetzt einfach als Variablen betrachten, können wir irgendwelche Zahlen, z.B. molare Massen einsetzen.


Der zweite Schlag (Teil) wird durch die Funktion "calc" gemacht, eim klassicher MatheParser.
Als Vorbereitung muss noch festgelegt werden, mit welchen Zahlen, wir unsere Variablen (Elemente) ersetzen. Dazu wird der ValueListeditor in Fmol gespeichert (Man hätte hier auch direkt den Valuelisteditor nehmen können, aber so kann man Fmol auch mal anders, z.B. durch ein Stringrid oder aus einer Datei füllen)
Also wir brauchen die Funktion calc und die StringListe Fmol, in der jeder einzelne String durch "Element=molare Masse" besetzt ist.
Und jetzt kommt die rekursive Funktion calc (die als Hilfe noch pos0 benutzt). Schau dir dazu mal folgenden Thread an: rekursiver Algorithmus
In Beitrag #13 hatte ich damals eine PP-Präsentation erstellt. Die Funktion calc heißt dort TTR.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat