Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > Coding Releases > Coding Snippets
You last visited: Today at 01:47

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



String Term Rechner [Delphi]

Discussion on String Term Rechner [Delphi] within the Coding Snippets forum part of the Coding Releases category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Feb 2009
Posts: 1,137
Received Thanks: 573
String Term Rechner [Delphi]

Hey ho Leute,

für ein aktuelles Projekt brauchte ich eine Funktion die Terme die als String angegeben werden ausrechnen kann. Da so etwas bestimmt jeder mal gebrauchen kann stelle ich diese für euch zur freien Verfügung.

Ist zwar in Delphi geschrieben, aber wer nicht grade vollends blöd ist sollte das einfach in andere Sprachen übersetzten können.

Das ganze kennt die befehle +, -, *, /, sowie POW was für hoch steht, und ROOT was für wurzel steht (So ist 2 POW 3 also 2³ und 2 ROOT 4 die quadratwurzel (2te wurzel) aus 4)

Es werden multiple klammer ebenen unterstützt, aber wichtig ist dass operatoren und zahlen durch leerstellen getrennt sind, d.h. 3+2 ist nicht gültig, 3 + (1 + 2) schon

Vllt baue ich noch ein paar sachen wie sinus und cosinus ein, aber so funktioniert es vorerst schon recht gut (auch wenn es wohl nicht die performanteste lösung ist)

Code:
uses Math;

type
  TOperator = (opNil, opAdd, opSub, OpMulti, OpDiff, opPow, opRoot);
  PValue = ^TValue;

  TValue = record
    Op: TOperator;
    Val: Real;
  end;

function Evaluate(Inp: string): Real;
  procedure Calc(ValLst: TList; i: Integer);
  var
    val1, val2: PValue;
    z: Integer;
  begin
    val1 := ValLst[i];
    val2 := ValLst[i + 1];
    if (val1^.Op = opAdd) or (val1^.Op = opSub) then
    begin
      if (val2^.Op = OpMulti) or (val2^.Op = OpDiff) or (val2^.Op = opRoot) or
        (val2^.Op = opPow) then
        Calc(ValLst, i + 1);
    end
    else if (val1^.Op = OpMulti) or (val1^.Op = OpDiff) then
    begin
      if (val2^.Op = opRoot) or (val2^.Op = opPow) then
        Calc(ValLst, i + 1);
    end;
    case val1^.Op of
      opAdd:
        begin
          val1^.Op := val2^.Op;
          val1^.Val := val1^.Val + val2^.Val;
        end;
      opSub:
        begin
          val1^.Op := val2^.Op;
          val1^.Val := val1^.Val - val2^.Val;
        end;
      OpMulti:
        begin
          val1^.Op := val2^.Op;
          val1^.Val := val1^.Val * val2^.Val;
        end;
      OpDiff:
        begin
          val1^.Op := val2^.Op;
          val1^.Val := val1^.Val / val2^.Val;
        end;
      opPow:
        begin
          val1^.Op := val2^.Op;
          val1^.Val := Power(val1^.Val, val2^.Val);
        end;
      opRoot:
        begin
          val1^.Op := val2^.Op;
          val1^.Val := Power(val2^.Val, 1 / val1^.Val);
        end;
    end;
    Dispose(ValLst[i + 1]);
    ValLst.Delete(i + 1);
  end;

  function IsFloat(S: string): boolean;
  var
    f: extended;
  begin
    Result := TextToFloat(PChar(S), f, fvExtended);
  end;

  function Eval(str: string; var i: Integer): Real;
  var
    tmp: string;
    Vals: TList;
    x: Integer;
    tmpVal: PValue;
  begin
    Vals := TList.Create;
    tmpVal := nil;
    try
      // Zwischenspeicher
      tmp := '';
      repeat
        inc(i);
        // Wenn leer, nach einem operator oder zahl des terms
        if (str[i] = ' ') then
        begin
          // Wenn es ein Operator ist
          if tmp = '+' then
          begin
            tmpVal^.Op := opAdd;
          end
          else if tmp = '-' then
          begin
            tmpVal^.Op := opSub;
          end
          else if tmp = '*' then
          begin
            tmpVal^.Op := OpMulti;
          end
          else if tmp = '/' then
          begin
            tmpVal^.Op := OpDiff;
          end
          else if tmp = 'POW' then
          begin
            tmpVal^.Op := opPow;
          end
          else if tmp = 'ROOT' then
          begin
            tmpVal^.Op := opRoot;
          end
          else if IsFloat(tmp) then // Wenn es eine zahl ist (zahl immer vor op)
          begin
            if not Assigned(tmpVal) then
              new(tmpVal); // Neue Value erstellen
            tmpVal^.Val := StrToFloat(tmp); // zahl setzen
            tmpVal^.Op := opNil; // Operator auf nil
          end;

          if Assigned(tmpVal) then // wenn zahl erstellt
            if (tmpVal^.Op <> opNil) then // Und operator gesetzt
            begin
              Vals.Add(tmpVal); // Zur liste hinzufügen
              tmpVal := nil;
            end;

          tmp := '';
        end
        else if str[i] = '(' then // Bei Subterm
        begin
          if tmpVal = nil then
            new(tmpVal); // Neue Value erstellen
          tmpVal^.Val := Eval(str, i); // zahl setzen
          inc(i);
          tmpVal^.Op := opNil; // Operator auf nil
        end
        else if str[i]<>')' then
          tmp := tmp + str[i];
        if ((i = Length(str)) or (str[i] = ')')) then
        begin
          if IsFloat(tmp) then
          begin
            if not Assigned(tmpVal) then
              new(tmpVal); // Neue Value erstellen
            tmpVal^.Val := StrToFloat(tmp); // zahl setzen
            tmpVal^.Op := opNil; // Operator auf nil
          end;
          if Assigned(tmpVal) then
            Vals.Add(tmpVal);
        end;
      until ((str[i] = ')') Or (i > Length(str))); // wiederholen für jedes zeichen bis subterm oder zeilen ende
      // Rechenen
      repeat
        x := 0;
        repeat
          Calc(Vals, x);
          inc(x);
        until (x >= Vals.Count - 2);
      until (Vals.Count = 1);
      Result := PValue(Vals[0])^.Val;
    finally
      for x := 0 to Vals.Count - 1 do
        Dispose(Vals[x]);
      Vals.Free;
    end;
  end;

var
  i: Integer;

begin
  i := 0;
  result:=Eval(Inp, i);
end;
warfley is offline  
Thanks
2 Users
Old 12/28/2014, 14:29   #2



 
Serraniel's Avatar
 
elite*gold: 0
The Black Market: 205/1/0
Join Date: May 2010
Posts: 6,853
Received Thanks: 5,106
Danke, finde ich ist ein hilfreiches Snippet für die, die mit Delphi arbeiten (wie ich manchmal).
Serraniel is offline  
Reply


Similar Threads Similar Threads
[Visual Basic] [Problem] String auslesen/String zufällig wählen
05/06/2012 - General Coding - 4 Replies
Code: #include <GUIConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Name Generator", 236, 299, 815, 246) $Input1 = GUICtrlCreateInput("Username", 24, 72, 185, 21) $Input2 = GUICtrlCreateInput("Username", 24, 104, 185, 21) $Input3 = GUICtrlCreateInput("Username", 24, 136, 185, 21) $Input4 = GUICtrlCreateInput("Username", 24, 168, 185, 21) $Input5 = GUICtrlCreateInput("Username", 24, 200, 185, 21)
[VB08]String in String mit mehreren Funden
08/08/2011 - .NET Languages - 6 Replies
Hey, bin gerade auf ein Problem gestoßen, an dem ich mir seit 3 Stunden die Zähne ausbeiße. Ich will eine Funktion schreiben, die der _StringBetween Funktion von AutoIt gleich ist. _StringBetween gibt in einem Array alle Strings zwischen zwei SubStrings und dem ganzen String aus. Die Ausgabe bei _StringBetween("<h1>test1</h1>&l t;h1>test2</h1>", "<h1>", "</h1>") wäre also idealer Weiße ein Array (x = "test1", x = "test2")... da man in VB08 kein Array returnen kann, komme ich aber einfach...
Den Term in einem String ausrechnen
08/07/2009 - AutoIt - 3 Replies
$variable="17*8+123*3*4-13/1" Msgbox(0,"test",$variable) Wäre nett wenn mir jemand helfen könnte : Ich will nicht dass der ganze String in der Textbox gezeigt wird sondern nur das Ergebnis , gibt es dazu ne UDF oder etwas ähnliches ? habe mich schon zu Tode gesucht ... P.S. Bitte kommt mir nicht mit "Das kann man doch sicher auch anders machen" ,"man muss es doch nicht unbedingt als String speichern" .



All times are GMT +1. The time now is 01:49.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.