Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Welche Methode zum Parsen von chemischen Formeln? (https://www.delphipraxis.net/90718-welche-methode-zum-parsen-von-chemischen-formeln.html)

Nagetier 26. Apr 2007 21:26

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Ok, danke ;)

Allerdings weiß ich auch nicht, was ich nicht verstehe, da ich halt einfach nichts verstehe will man fast meinen, vll fehlt auch nur der Knackpunkt, wos dann Klick macht und aha, wäre nicht das erste mal bei mir :>

Ich versuchs mal weiter übers We!

Danke

sirius 27. Apr 2007 09:52

Re: Welche Methode zum Parsen von chemischen Formeln?
 
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.

Nagetier 27. Apr 2007 14:12

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Super!

Habe ihn jetzt besser verstanden, und auch mal eingebaut, klappt ganz nett, allerdings habe ich meine Daten in einer Stringlist gespeichert, und möchte diese bei Fmol nutzen, wie gebe ich Fmol nun an, welche Spalten genutzt werden sollen?

Aber sonst, tip top, danke ;)

sirius 27. Apr 2007 14:50

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Meinst du jetzt StringList oder Stringgrid?

Also bei einer Stringlist brauchst du nur assign verwenden (sowie ich bei den Valuelisteditor) bei allen anderen musst du dir das Fmol halt irgendwie zusammensetzen. Wenn es keine günstige Methode gibt, dann halt Schritt für Schritt:
Delphi-Quellcode:
fmol:=Tstringlist.create;
try
  fmol.add('H=1,004');
  fmol.add('O=16');
  //so wird die Liste erstellt, das "=" ist wichtig damit ich hinterher den Namen vom Wert unterscheiden kann (siehe NameValueseparator"), falls du das "=" anderweitig in der Liste benutzt, müsstest du eben den fmol.namevaluesparator ändern
 
  //das anfügen geht natürlich auch anders
  fmol.add(s); //wenn s ein string ist
  //oder
  fmol.add(stringgrid1.cells[2,1]+'='+stringgrid1.cells[5,1]);
  //oder
  for i:=1 to 10 do fmol.add((stringgrid1.cells[2,i]+'='+stringgrid1.cells[5,i]);
 

finally
  fmol.free;
end;

Nagetier 27. Apr 2007 15:04

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Ok, habs jetz gelöst mit einem StringGrid, :hello:

Wunderbar, wunderbar, kann ich jetzt evtl noch in einem Stringgrid die Verwendeten Elemente vll noch deren Anzahl, sowie die Molare Masse anzeigen lassen?

DP-Maintenance 27. Apr 2007 17:54

DP-Maintenance
 
Dieses Thema wurde von "SirThornberry" von "Programmieren allgemein" nach "Object-Pascal / Delphi-Language" verschoben.

Nagetier 30. Apr 2007 11:30

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Also ich hab das jetztmal versucht, mit der Tabelle, dafür müsste ich doch aus dem String "term" einen TStrings abgreifen, zum einen die Chemischen Symbole und zum anderen dann noch einmal die Molaren Massen, und dann das ganze per
Delphi-Quellcode:
Stringgrid.Rows[0] := term2;
einfügen, oder?

So klappt es nicht, irgendwie hab ich da n Denkfehler wohl drinne, da hab ich einfach versucht, sozusagen die erste "Spalte" abzugreifen, aber das geht net so...

Delphi-Quellcode:
function Tform1.Berechnen(term:string):double; //Berechnet Masse
var p:integer;
st : string;
tst : Tstrings;
begin
  if pos0('+',term,p) then
    result:=Berechnen(copy(term,1,p-1))+Berechnen(copy(term,p+1,length(term)))
  else if pos0('*',term,p) then
    result:=Berechnen(copy(term,1,p-1))*Berechnen(copy(term,p+1,length(term)))
  else if term[1]='(' then
    result:=Berechnen(copy(term,2,length(term)-2))
  else if term[1] in ['a'..'z','A'..'z'] then
//Molare Masse in Fmol wird gesucht
    result:=strtofloat(Fmol.ValueFromIndex[Fmol.indexofname(term)])
  else begin
    result:=strtofloat(term);
       end;
    st :=Fmol.ValueFromIndex[Fmol.indexofname(term)];
    tst := st[1];
    MolGrid.Rows[0]:= tst;
end;

sirius 30. Apr 2007 13:44

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Nee, das klappt ganz sicher nicht.
Bist du mal mit einem Debugger drüber gegangen? Du dürftest schon bei der Zuweisung von st einen Fehler bekommen.
Du hast wahrscheinlich noch nie rekursive Funktionen geschrieben. So einfach kannst du da nicht drin rumschreiben.
Ich sehe auch leider aus dem Quelltext nicht, was du willst. Bzw was anders ist, als das, was ich schon vorgeschlagen hatte.

Dann noch zwei Sachen:
1. Mein Programm war nur ein schnelles TestProg. Du solltest den Parser besser unter eine eigene Klasse legen und nicht bei TForm1 lassen.
2. hab ich grad vergessen :?

Nagetier 30. Apr 2007 14:29

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Ich hab vor die Zuordnungen, die er ja macht, zum parsen der Formeln einfach in eine Tabelle zu schreiben, er ließt ja aus Fmol die Werte aus, und ersetzt sie zum rechnen...

Jetzt will ich, dass der Nutzer dies als Ausgabe in einem Stringgrid sieht...
Allerdings, wie du schon sagst, will das nicht so einfach gehen, wie mans gerne hätte.

Wegen den Zuordnungen, das is noch dein Programm in dem ich rumschreib, ich hab das ganze für mein Proggi eh nochma abgeschrieben, sonst hät ich das vll nie begriffen ;)

Wie auch immer, muss halt versuchen das da rauszufummeln, was im Programm rumschwirrt ;)

//Achja, im Quelltext hab ich TStrings stehen, hier im Board wohl net, lol :>

//Edit2: Jetzt wo dus sagst mit dem TForm1 un so, in meinen Programm heißt das sogar noch TForm1, 0ldschool quasi^^

sirius 30. Apr 2007 15:07

Re: Welche Methode zum Parsen von chemischen Formeln?
 
Zitat:

Zitat von Nagetier
Ich hab vor die Zuordnungen, die er ja macht, zum parsen der Formeln einfach in eine Tabelle zu schreiben, er ließt ja aus Fmol die Werte aus, und ersetzt sie zum rechnen...

Ja, aber er list sie nur aus, wenn der Term auch gerade nur das Element betrifft. Ansonsten interessiert er sich nicht für fmol. Zumindest nicht bei diesem Aufruf.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:11 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz