string ausrechnen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Lukas-P
Beiträge: 262
Registriert: 07.10.2004 12:03

string ausrechnen

Beitrag von Lukas-P »

Hallo :-D


Wie kan ich eienn string ausrechenen (hört sich irgendwie komsich an)

Also so mein ich das etwa:


ergebnis=ausrechnen("10*2+9/5*3")


Ich könnte das eigentlich auch programmieren nur das is mir zuviel arbeit also gibt es da irgendwas? :allright:
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Beitrag von 125 »

hmm da musste ne routine schreiben die das selectet splitttet geteil tsachen zuerst rechnet dan plus minus von rechts nach Links....
Schätzung an Arbeitszeit:max 3-4 stunden :)
Benutzeravatar
Lukas-P
Beiträge: 262
Registriert: 07.10.2004 12:03

Beitrag von Lukas-P »

Ich hab was bei den user Libs gefunden :-D

Code: Alles auswählen

Procedure.l Eval(Input.s) 
  Dim Priority.s(20) 
  k = 0 
  *pInput.BYTE = @Input 
  Repeat 
    If *pInput\b = '(' 
      
      k+1 
        
    ElseIf *pInput\b = ')' 
      
      *r.BYTE = @Priority(k) 
      last_op = 0 
      number.s = "" 
      lastchrnum = 1 
      P2_Start_Op = -1 
      Repeat 
        If *r\b >= $30 And *r\b <= $39 
          number + Chr(*r\b) 
          lastchrnum = 1 
          
        Else ;*r\b ist keine ASCII-Ziffer 
          
          
          last_op2 = last_op 
          If lastchrnum 
            If *r\b = '+' 
              If last_op > 2 
                If last_op = 3 
                  P2_Result * Val(number) 
                ElseIf last_op = 4 
                  P2_Result / Val(number) 
                EndIf 
                If P2_Start_Op = 0 
                  Result = P2_Result 
                ElseIf P2_Start_Op = 1 
                  Result + P2_Result 
                ElseIf P2_Start_Op = 2 
                  Result - P2_Result 
                EndIf 
                P2_Start_Op = -1 
              EndIf 
              
              last_op = 1 
            ElseIf *r\b = '-' 
              If last_op > 2 
                If last_op = 3 
                  P2_Result * Val(number) 
                ElseIf last_op = 4 
                  P2_Result / Val(number) 
                EndIf 
                If P2_Start_Op = 0 
                  Result = P2_Result 
                ElseIf P2_Start_Op = 1 
                  Result + P2_Result 
                ElseIf P2_Start_Op = 2 
                  Result - P2_Result 
                EndIf 
                P2_Start_Op = -1 
              EndIf 
              
              last_op = 2 
            ElseIf *r\b = '*' 
              If last_op < 3 
                P2_Start_Op = last_op 
                P2_Result = Val(number) 
              EndIf 
              last_op = 3 
            ElseIf *r\b = '/' 
              If last_op < 3 
                P2_Start_Op = last_op 
                P2_Result = Val(number) 
              EndIf 
              last_op = 4 
            EndIf 
            
            If last_op2 = 0 And last_op < 3 
              Result = Val(number) 
            ElseIf last_op2 = 1 And last_op < 3 
              Result + Val(number) 
            ElseIf last_op2 = 2 And last_op < 3 
              Result - Val(number) 
            ElseIf last_op2 = 3 
              P2_Result * Val(number) 
            ElseIf last_op2 = 4 
              P2_Result / Val(number) 
            EndIf 
            
            number = "" 
          ElseIf *r\b = '-' 
            If number = "" 
              number = "-" 
            Else 
              number = "" 
            EndIf 
          EndIf 
          
          
          
          lastchrnum = 0 
          
        EndIf 
        
        
        *r+1 
      Until *r\b = 0 
      If last_op = 0 
        Result = Val(number) 
      ElseIf last_op = 1 
        Result + Val(number) 
      ElseIf last_op = 2 
        Result - Val(number) 
      ElseIf last_op = 3 
        P2_Result * Val(number) 
      ElseIf last_op = 4 
        P2_Result / Val(number) 
      EndIf 
      
      If P2_Start_Op = 0 
        Result = P2_Result 
      ElseIf P2_Start_Op = 1 
        Result + P2_Result 
      ElseIf P2_Start_Op = 2 
        Result - P2_Result 
      EndIf 
      k-1 
      If k < 0 
        ProcedureReturn 0 
      EndIf 
      Priority(k)+Str(Result) 
      
    ElseIf *pInput\b = 0 ; ---ENDE vom String--- 

      
      *r.BYTE = @Priority(k) 
      last_op = 0 
      number = "" 
      lastchrnum = 1 
      P2_Start_Op = -1 
      Repeat 
        If *r\b >= $30 And *r\b <= $39 
          number + Chr(*r\b) 
          lastchrnum = 1 
          
        Else ;*r\b ist keine ASCII-Ziffer 

          
          last_op2 = last_op 
          If lastchrnum 
            If *r\b = '+' 
              If last_op > 2 
                If last_op = 3 
                  P2_Result * Val(number) 
                ElseIf last_op = 4 
                  P2_Result / Val(number) 
                EndIf 
                If P2_Start_Op = 0 
                  Result = P2_Result 
                ElseIf P2_Start_Op = 1 
                  Result + P2_Result 
                ElseIf P2_Start_Op = 2 
                  Result - P2_Result 
                EndIf 
                P2_Start_Op = -1 
              EndIf 
              
              last_op = 1 
            ElseIf *r\b = '-' 
              If last_op > 2 
                If last_op = 3 
                  P2_Result * Val(number) 
                ElseIf last_op = 4 
                  P2_Result / Val(number) 
                EndIf 
                If P2_Start_Op = 0 
                  Result = P2_Result 
                ElseIf P2_Start_Op = 1 
                  Result + P2_Result 
                ElseIf P2_Start_Op = 2 
                  Result - P2_Result 
                EndIf 
                P2_Start_Op = -1 
              EndIf 
              
              last_op = 2 
            ElseIf *r\b = '*' 
              If last_op < 3 
                P2_Start_Op = last_op 
                P2_Result = Val(number) 
              EndIf 
              last_op = 3 
            ElseIf *r\b = '/' 
              If last_op < 3 
                P2_Start_Op = last_op 
                P2_Result = Val(number) 
              EndIf 
              last_op = 4 
            EndIf 
            
            If last_op2 = 0 And last_op < 3 
              Result = Val(number) 
            ElseIf last_op2 = 1 And last_op < 3 
              Result + Val(number) 
            ElseIf last_op2 = 2 And last_op < 3 
              Result - Val(number) 
            ElseIf last_op2 = 3 
              P2_Result * Val(number) 
            ElseIf last_op2 = 4 
              P2_Result / Val(number) 
            EndIf 
            
            number = "" 
          ElseIf *r\b = '-' 
            If number = "" 
              number = "-" 
            Else 
              number = "" 
            EndIf 
          EndIf 

          
          
          lastchrnum = 0 
          
        EndIf 
        
        
        *r+1 
      Until *r\b = 0 
      If last_op = 0 
        Result = Val(number) 
      ElseIf last_op = 1 
        Result + Val(number) 
      ElseIf last_op = 2 
        Result - Val(number) 
      ElseIf last_op = 3 
        P2_Result * Val(number) 
      ElseIf last_op = 4 
        P2_Result / Val(number) 
      EndIf 
      
      If P2_Start_Op = 0 
        Result = P2_Result 
      ElseIf P2_Start_Op = 1 
        Result + P2_Result 
      ElseIf P2_Start_Op = 2 
        Result - P2_Result 
      EndIf 
      
      ProcedureReturn Result 
      
    Else 
      Priority(k) + Chr(*pInput\b) 
    EndIf 
    *pInput+1 
  ForEver 
EndProcedure 
traumatic
Beiträge: 478
Registriert: 27.11.2004 15:42

Beitrag von traumatic »

125 hat geschrieben:Schätzung an Arbeitszeit:max 3-4 stunden :)
Is klar... dann schreib mir bitte mal einen Infix zu Postfix Konverter, der
auch Floats berücksichtigt und Variablen mit einer Länge >= 1.

Mach mir mal ein Angebot, wird ja wohl nicht so teuer.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Was ist InFix und PostFix?

So eine Rechenroutine ist wirklich leicht selbst zu programmieren. In 3-4 Stunden sollte das zu schaffen sein, solange es bei +, -, *, / und Klammern bleibt.
Benutzeravatar
125
Beiträge: 1322
Registriert: 19.09.2004 16:52
Wohnort: Neu Wulmstorf (Hamburg)
Kontaktdaten:

Beitrag von 125 »

Was ist Infix und Postfix? Und wenn dus so drauf anlegst dann werde ich gernen einen Stringrechner schreiben.... Ich würde wenn ich durcharbeite nur 4 Std. benötigen (muss doch nur die Zahlen zwischen denn trenzzeichen auslesen und sortiern und durchrechnen)

Oder etwa nicht? :?
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Noch sone kleine Alternative von mir:

Code: Alles auswählen

Procedure.s GetContent(String.s, Pos.l, First.b, Last.b) ;String = "dd(hallo)xyz", 3, '(', ')'
  Protected Content.s, *p.BYTE, AnzKl.l
  *p = @String + Pos
  While *p\b
    If *p\b = First
      AnzKl.l + 1
    ElseIf *p\b = Last
      AnzKl - 1
      If AnzKl <= -1
        Break
      EndIf
    EndIf
    Content + Chr(*p\b)
    *p + 1
  Wend
  
  ProcedureReturn Content
EndProcedure

Procedure.s CalcBiExpression(ContL.s, Op.s, ContR.s) ; A+b oder A*b ...
  Protected Result.s
  
  Select Op
    Case "*"
      Result = Str(Val(ContL) * Val(ContR))
    Case "/"
      Result = Str(Val(ContL) / Val(ContR))
    Case "+"
      Result = Str(Val(ContL) + Val(ContR))
    Case "-"
      Result = Str(Val(ContL) - Val(ContR))
  EndSelect
  
  
  ProcedureReturn Result.s
EndProcedure


Procedure.s ProcessExpression(Exp.s)
  Protected *p.BYTE, v.s, zw.l, ContL.s, ContR.s, Op.s, Cont.s
  *p = @Exp
  
  
  ;/ Search for ()
  While *p\b
    If *p\b = '('
      Cont = GetContent(Exp, *p-@Exp+1, '(', ')')
      v.s = ProcessExpression(Cont)
      Exp = ReplaceString(Exp, "("+Cont+")", v)
      *p  = @Exp
    ElseIf *p\b = ')'
      Debug "Fehler: Klammer nicht geöffnet!"
    EndIf
    *p + 1
  Wend
  
  
  ;/ Search for * bzw. /
  *p = @Exp
  While *p\b
    If *p\b = '*' Or *p\b = '/'
      zw = *p ;Zwischenspeichern
      Op = Chr(*p\b)
      ; Gehe zurück bis ein Operator kommt
      *p - 1
      ContL = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b 
        ContL = Chr(*p\b) + ContL
        *p - 1
      Wend
      
      *p = zw
      
      ; Gehe vorwärts bis Operator kommt
      *p + 1
      ContR = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b 
        ContR = ContR + Chr(*p\b)
        *p + 1
      Wend
      
      v = CalcBiExpression(ContL, Op, ContR)
      Exp = ReplaceString(Exp, ContL+Op+ContR, v)
      *p = @Exp
    EndIf
    *p + 1
  Wend
  
  ;/ Search for + bzw. -
  *p = @Exp
  While *p\b
    If *p\b = '+' Or *p\b = '-'
      zw = *p ;Zwischenspeichern
      Op = Chr(*p\b)
      ; Gehe zurück bis ein Operator kommt
      *p - 1
      ContL = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b 
        ContL = Chr(*p\b) + ContL
        *p - 1
      Wend
      
      *p = zw
      
      ; Gehe vorwärts bis Operator kommt
      *p + 1
      ContR = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b 
        ContR = ContR + Chr(*p\b)
        *p + 1
      Wend
      
      v = CalcBiExpression(ContL, Op, ContR)
      Exp = ReplaceString(Exp, ContL+Op+ContR, v)
      *p = @Exp
    EndIf
    *p + 1
  Wend
  
  
  ProcedureReturn Exp
EndProcedure




Expression.s = "(2*2)+2*(3+4*(4+1))*2"
Expression = RemoveString(Expression, " ") ;im Parser
Res.s = ProcessExpression(Expression)
Debug "#############  RESULTAT  #############"
Debug Res
Hab ich mal so als kleine Übung geschrieben (nicht auf Fehler geprüft!).

Und wenn jemand and der Infix zu Postfix (bei mir ohne Floats, dafür mit Variablen, Funktionen, Strings, ...) interessiert ist, hab ich für meinen kleinen Compiler geschrieben, wobei das natürlich dort jetzt fest eingebaut ist und ich das nicht so einfach hier rein kopieren kann.
Is a bissl a längerer Code, also bei Interesse per E-Mail melden.

cu
Remi :)
MARTIN
Beiträge: 454
Registriert: 08.09.2004 14:03
Wohnort: Kiel

Beitrag von MARTIN »

Was ist Infix und Postfix?
In diesem zusamenhang ist das das hier:http://de.wikipedia.org/wiki/Affix#Affi ... Mathematik
Amilo 1667|Suse Linux 10.1_64bit/WinXP |PB 4.00/3.94
Antworten