Berechnung von Strings ???

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

porcus

Betreff: Berechnung von Strings ???

BeitragSo, Feb 11, 2007 16:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen!

Weis jemand wie man eine Aufgabe, die nur als String vorliegt berechnet?

z.B.: Local aufgabe:String="(5-3)*(96/(2+1))"

Artemis

BeitragSo, Feb 11, 2007 17:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Für BlitzClassic gibt es hier eine Funktion.

Müsste sich für BlitzMax umschreiben lassen.

BtbN

BeitragSo, Feb 11, 2007 20:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Nimm Lua.
 

porcus

BeitragMo, Feb 12, 2007 20:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab jetzt versucht, dass Teil von ShadowTurtle umzuschreiben, aber
irgendwie funzt des net. Kann mir bitte jemand helfen ?


Code: [AUSKLAPPEN]

Print "Term Emu. : 10+5 = " + MathToString$("10+5")
Print "BB Term : 10+5 = " + (10+5)
Print
Print "Term Emu. : 10-((1+(1-2))-1) = " + MathToString$("10-((1+(1-2))-1)")
Print "BB Term : 10-((1+(1-2))-1) = " + (10-((1+(1-2))-1))
Print
Print "Term Emu. : 5*3*(2+5)*3 = " + MathToString$("5*3*(2+5)*3")
Print "BB Term : 5*3*(2+5)*3 = " + (5*3*(2+5)*3)
Print
Print "Term Emu. : 2+(10+(10)*-1)*20+5 = " + MathToString$("2+(10+(10)*-1)*20+5")
Print "BB Term : 2+(10+(10)*-1)*20+5 = " + (2+(10+(10)*-1)*20+5)
Print
Print "Term Emu. : 5*3*(2+5)*3 = " + MathToString$("5*3*(2+5)*3")
Print "BB Term : 5*3*(2+5)*3 = " + (5*3*(2+5)*3)
Print
Print "Term Emu. : (5+2)*-1 = " + MathToString$("(5+2)*-1")
Print "BB Term. : (5+2)*-1 = " + ((5+2)*-1)
Print
Print "Term Emu. : (5+2)*-1 = " + MathToString$("(10*2)+(11*3)*(18-9*16+(2*4))")
Print "BB Term : (10*2)+(11*3)*(18-9*16+(2*4)) = " + ((10*2)+(11*3)*(18-9*16+(2*4)))

WaitKey
End

Function MathToString$(TheMath$, unit = 0, divnow = 0)
Local MyParam$ = "*/^+-=<>&|%@", MyNumbs$ = "0123456789.", MyDivParam$ = "*/^"
Local Ziffer$, ScanPos, MathAnswer#, MathArt$, MathPower#, OldMathPower#
Local Scan, ScanNumber$, OldScanNumber$, MathScan$, MyScanText$

Local bscan, bscannow, bscanhave, ScanPosA, ScanPosB

Local deScan, deMathScan$, deMath

Local debsScan

TheMath$ = Lower(TheMath$)
TheMath$ = Replace(TheMath$, "and", "&")
TheMath$ = Replace(TheMath$, "xor", "@")
TheMath$ = Replace(TheMath$, "or", "|")
TheMath$ = Replace(TheMath$, "mod", "%")

MathScan$ = Replace(TheMath$, " ", "")
debsScan = 1

While bscan < Len(MathScan$)
bscan = bscan + 1
If Mid$(MathScan$, bscan, 1) = "(" Then
ScanPosA = bscan
bscannow = 1
While bscannow
If Mid$(MathScan$, bscan, 1) = "(" Then bscanhave = bscanhave + 1
If Mid$(MathScan$, bscan, 1) = ")" Then bscanhave = bscanhave - 1
If bscanhave = 0 Then bscannow = 0
bscan = bscan + 1
If KeyDown(1) Then End
Wend

ScanPosB = bscan

MyScanText$ = Mid$(MathScan$, ScanPosA+1, ScanPosB - ScanPosA - 2)

MyScanText$ = MathToString$(MyScanText$, unit + 1)
MathScan$ = Replace(MathScan$, Mid$(MathScan$, ScanPosA, ScanPosB - ScanPosA), MyScanText$)
bscan = 0
End If

If KeyDown(1) Then End
Wend

#NewMathScan

deMathScan$ = MathScan$

Scan = Int(InMid$(MathScan$, MyParam$))
If Scan Then
ScanNumber$ = Mid$(MathScan$, 1, Scan-1)
MathScan$ = Mid$(MathScan$, Scan)
MathAnswer = val2(ScanNumber$)
Else
Return MathScan$
End If

deScan = 1

While Not MathScan$ = ""
uu$ = MathScan$

MathArt$ = Mid$(MathScan$, 1, 1)
MathScan$ = Mid$(MathScan$, 2)

If Mid$(MathScan$,1,1) = "-" Then
MathPower# = -1
MathScan$ = Mid$(MathScan$, 2)
Else
MathPower# = 1
End If

Scan = Int(InMid$(MathScan$, MyParam$))
OldScanNumber$ = ScanNumber$
OldMathPower# = MathPower#
ScanNumber$ = Mid$(MathScan$, 1, Scan-1)

MathScan$ = Mid$(MathScan$, Len(ScanNumber$)+1)

If MathArt$ = "+" Then
MathAnswer# = MathAnswer# + (val2(ScanNumber$)*MathPower#)
ElseIf MathArt$ = "-" Then
MathAnswer# = MathAnswer# - (val2(ScanNumber$)*MathPower#)
ElseIf MathArt$ = "*" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) * (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "*-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "*" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "/" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) / (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "/-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "/" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "^" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) ^ (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "^-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "^" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "=" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) = (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "=-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "=" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "<" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) < (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "<-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "<" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = ">" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) > (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + ">-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + ">" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "&" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) And (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "&-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "&" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "|" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) Or (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "|-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "|" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "%" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) Mod (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "%-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "%" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
ElseIf MathArt$ = "@" Then
'MathAnswer# = Xor(val2(OldScanNumber$)*OldMathPower#,val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "@-" + ScanNumber$, "-" + MathAnswer)
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "@" + ScanNumber$, MathAnswer)
End If
Goto NewMathScan
Else
Return "SYNTAX ERROR"
End If
Wend

Return MathAnswer
End Function

Function InMid$(A$, B$)
Local C, Q, W
C = 0
For Q = 1 To Len(A$)
For W = 1 To Len(B$)
If (Mid$(A$, Q, 1) = Mid$(B$, W, 1)) And C = 0
C = Q
Exit
EndIf
Next
If C>0 Then Exit
Next
Return C
End Function

Function val2#(sstring$)
Local temp#=0
Local decimal=0
Local sign=1
Local a
Local b
Local c
Local base=10
a=Instr(sstring$,"-",1)
If a Then negative=-1
b=Instr(sstring$,"&",a+1)
If b Then
Select Mid$(sstring$,a+1,1)
Case "B", "b"
base=2
a=b+1
Case "O", "o"
base=8
a=b+1
Case "H", "h"
base=16
a=b+1
Default
base=10
End Select
End If
decimal=0
For b=a+1 To Len(sstring$)
c=Asc(Mid(sstring$,b,1))
Select c
Case 44
Goto skip
Case 45
sign=-sign
Case 46
decimal=1
Case 48,49,50,51,52,53,54,55,56,57 ';"0" To "9"
temp#=temp*base+c-48
If decimal Then decimal=decimal*base
Case 65,66,67,68,69,60 ';"A" To "F"
If base=16 Then
temp#=temp#*base+c-55
If decimal Then decimal=decimal*base
Else
Goto fini
EndIf
Case 97,98,99,100,101,102 ';"a" To "f"
If base=16 Then
temp#=temp#*base+c-87
If decimal Then decimal=decimal*base
Else
Goto fini
EndIf
Default
Goto fini
End Select
#skip
Next
#fini
If decimal Then temp#=temp#/decimal

If negative = -1 Then
Return -(temp#*sign)
Else
Return temp#*sign
End If
End Function

BtbN

BeitragMo, Feb 12, 2007 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Au weia, formatier das erstmal richtig! Da wird man ja nicht schlau draus.
Und Nochma: Nimm Lua!

Clonker

BeitragMo, Feb 12, 2007 22:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab mal vor längerer Zeit so etwas geschrieben.

Code: [AUSKLAPPEN]

Strict
Framework brl.basic
Import BRL.glmax2d

Graphics 640,480,0,60,1
Local term:String = "((5+5)*10)/((5^2)-5)"
Local zeit,z2,i,x:Float


zeit = MilliSecs()

For i = 1 To 1000
   calc(term)
Next

DrawText (MilliSecs()-zeit)+"ms",10,40

DrawText "1000 Berechnungen: " ,10,10
DrawText term+"="+calc(term),10,25


Flip

WaitKey()
End

Function calc:String(term:String)
   Local rech:String
   Local z1l:Int, z2l:Int, t:Int, i:Int, s:Int, rech_pos:Int
   Local zahl1:Double, zahl2:Double, erg:Double
   
   Function CheckChar:Int(t_chr:String)
      If Asc(t_chr)>=48 And Asc(t_chr)<=57 Then
         Return 1
      Else If t_chr="." Then
         Return 1
      Else If t_chr="+" Or t_chr="-" Then
         Return 2
      EndIf
   End Function
   
   Function Round_String:String(zahl:String)
      Return zahl[0..zahl.find(".")]+zahl[zahl.find(".")..zahl.find(".")+3]
   End Function
   
   Function Clean_Term:String(_term:String)
      _term = _term.replace(" ","")
      
      While _term.find("+-") <> -1
         _term = _term.replace("+-","-")
      Wend
      While _term.find("-+") <> -1
         _term = _term.replace("-+","-")
      Wend
      While _term.find("++") <> -1
         _term = _term.replace("++","+")
      Wend
      While _term.find("--") <> -1
         _term = _term.replace("--","+")
      Wend
      Return _term
   End Function
   
   'Term säubern
   term = Clean_Term(term)   
   
   'Klammern auflösen
   While term.find("(") <> -1
      s=0
      t=0
      For i = 0 To term.Length
         If term[i..i+1] = "(" Then
            t = t + 1
            s=1
         EndIf
         If term[i..i+1] = ")" And s <> 0 Then
            t = t - 1
         EndIf
         
         If s <> 0 And t = 0 Then
            term=term[0..term.find("(")]+calc$(term[term.find("(")+1..i])+term[i+1..term.length]
            Exit
         EndIf
      Next
      term = Clean_Term(term)   
   Wend

   'Beginn des eigentlichen Rechnens
   For t=0 To 4
      If t = 0 Then rech:String = "^"
      If t = 1 Then rech:String = "/"
      If t = 2 Then rech:String = "*"
      If t = 3 Then rech:String = "-"
      If t = 4 Then rech:String = "+"
      
      term = term.replace("&","-")
      While term.find(rech) <> -1
            z1l = 0
            z2l = 0      
            rech_pos = term.find(rech)
            
            'Zahl vor dem Rechenzeichen
            While checkchar(term[rech_pos-z1l-1..rech_pos-z1l]) = 1
               z1l=z1l + 1
            Wend            
            If checkchar(term[rech_pos-z1l-1..rech_pos-z1l]) = 2 Then z1l=z1l+1
            
            'Wenn vor dem Rechenzeichen nichts steht: "-" durch "&" ersetzen
            If z1l = 0 Then
               If t=3 term = term[0..rech_pos]+"&"+term[rech_pos+1..term.length]
               If t=4 term = term[0..rech_pos]+term[rech_pos+1..term.length]
            EndIf
            'Zahl hinter dem Rechenzeichen
            If checkchar(term[rech_pos+z2l+1..rech_pos+2+z2l]) = 2 Then z2l=z2l+1
            While checkchar(term[rech_pos+z2l+1..rech_pos+2+z2l]) = 1
               z2l=z2l + 1
            Wend            
            
            'Wenn die länge der Zahlen größer null ist
            If z1l <> 0 And z2l <> 0 Then
               'Zahlen suchen
               zahl1 = Double(term[rech_pos-z1l..rech_pos])
               zahl2 = Double(term[rech_pos+1..rech_pos+1+z2l])
               
               'Rechnen
               If t = 4 Then erg = (zahl1+zahl2)
               If t = 3 Then erg = (zahl1-zahl2)
               If t = 2 Then erg = (zahl1*zahl2)
               If t = 1 Then erg = (zahl1/zahl2)
               If t = 0 Then erg = (zahl1^zahl2)
               
               'Ergebnis einfügen
               term = term[0..rech_pos-z1l] + String(erg) + term[rech_pos+1+z2l..term.length]
            EndIf
      Wend
   Next
   Return Round_String(term)
End Function

Viel Spaß damit Wink
Die exzessive Akkumulation von Fremdwörtern suggeriert pseudointellektuelle Kompetenz.

Athlon XP 2800|Radeon 9600 Pro|512MB DDR RAM|240GB Festplatte

BtbN

BeitragMo, Feb 12, 2007 22:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Wieso nimmst du nicht einfach LUA?
Das ist schnell, einfach zu benutzen, und erfüllt sogar mehr als nur den zweck.

Vertex

BeitragDi, Feb 13, 2007 0:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
SuperStrict

Framework BRL.StandardIO

Global In       : String, ..
       Position : Int, ..
       Token    : Byte

In = Input(">") + Chr(13)

Try
   Print("Result = " + Parse())
Catch Exception:Object
   Print("Error:~n~t" + Exception.ToString())
End Try

Function Parse:Int()
   GetToken()
   Return Command()
End Function

Function GetToken()
   If Position => Len(In) Then Throw("EOF")
   Token = In[Position]
   Position :+ 1
End Function

Function Match(Char:Byte)
   If Token = Char Then
      GetToken()
   Else
      Throw("Expected " + Chr(Char))
   EndIf
End Function

Function Command:Int()
   Local Result:Int
   
   Result = Expression()
   If Token = 13 Then
      Return Result
   Else
      Throw("EOF")
   EndIf
End Function

Function Expression:Int()
   Local Result:Int
   
   Result = Term()
   While Token = Asc("+") Or Token = Asc("-")
      If Token = Asc("+")
         GetToken()
         Result :+ Term()
      Else
         GetToken()
         Result :- Term()
      EndIf
   Wend

   Return Result
End Function

Function Term:Int()
   Local Result:Int
   
   Result = Factor()
   While Token = Asc("*") Or Token = Asc("/")
      If Token = Asc("*") Then
         GetToken()
         Result :* Factor()
      Else
         GetToken()
         Result :/ Factor()
      EndIf
   Wend

   Return Result
End Function

Function Factor:Int()
   Local Result:Int

   If Token = Asc("(") Then
      Match(Asc("("))
      Result = Expression()
      Match(Asc(")"))
   Else
      Result = Number()
   EndIf

   Return Result
End Function

Function Number:Int()
   Local Result:Int

   While Token => Asc("0") And Token <= Asc("9")
      Result = Result*10 + Digit()
   Wend

   Return Result
End Function

Function Digit:Int()
   Local Result:Int

   If Token => Asc("0") And Token <= Asc("9") Then
      Result = Token - Asc("0")
      Match(Token)
   Else
      Throw("Expected 0-9")
   EndIf

   Return Result
End Function


Als Beispiel mal 6*7+2*4 eintippen

mfg olli
vertex.dreamfall.at | GitHub

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group