This code basically takes a mathematical expression and evaluates it. The following code i have written in VB.net shamelessly taken from here : Expression Evaluation
which has been written in Java.
Public Function evaluate(expression As [String]) As Integer
Dim tokens As Char() = expression.ToCharArray()
' Stack for numbers: 'values'
Dim values As New Stack(Of UInteger)()
' Stack for Operators: 'ops'
Dim ops As New Stack(Of Char)()
For i As Integer = 0 To tokens.Length - 1
' Current token is a whitespace, skip it
If tokens(i) = " "c Then
Continue For
End If
' Current token is a number, push it to stack for numbers
If tokens(i) >= "0"c AndAlso tokens(i) <= "9"c Then
Dim sbuf As New StringBuilder(100)
'Dim sbuf As New String("", 128)
' There may be more than one digits in number
If i < tokens.Length AndAlso tokens(i) >= "0"c AndAlso tokens(i) <= "9"c Then
sbuf.Append(tokens(System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)))
End If
If sbuf Is Nothing AndAlso sbuf.ToString().Equals("") Then
Else
Dim intgr As Integer
Dim accpt As Boolean = Integer.TryParse(sbuf.ToString(), intgr)
If accpt = True Then
values.Push([Integer].Parse(sbuf.ToString()))
Else
Dim space As String = " "
values.Push(space)
End If
End If
' Current token is an opening brace, push it to 'ops'
ElseIf tokens(i) = "("c Then
ops.Push(tokens(i))
' Closing brace encountered, solve entire brace
ElseIf tokens(i) = ")"c Then
While ops.Peek() <> "("c
values.Push(applyOp(ops.Pop(), values.Pop(), values.Pop()))
End While
ops.Pop()
' Current token is an operator.
ElseIf tokens(i) = "+"c OrElse tokens(i) = "-"c OrElse tokens(i) = "*"c OrElse tokens(i) = "/"c Then
' While top of 'ops' has same or greater precedence to current
' token, which is an operator. Apply operator on top of 'ops'
' to top two elements in values stack
While Not ops.Count = 0 AndAlso hasPrecedence(tokens(i), ops.Peek())
values.Push(applyOp(ops.Pop(), values.Pop(), values.Pop()))
End While
' Push current token to 'ops'.
ops.Push(tokens(i))
End If
Next
' Entire expression has been parsed at this point, apply remaining
' ops to remaining values
While Not ops.Count = 0
values.Push(applyOp(ops.Pop(), values.Pop(), values.Pop()))
End While
' Top of 'values' contains result, return it
Return values.Pop()
End Function
Public Function hasPrecedence(op1 As Char, op2 As Char) As [Boolean]
If op2 = "("c OrElse op2 = ")"c Then
Return False
End If
If (op1 = "*"c OrElse op1 = "/"c) AndAlso (op2 = "+"c OrElse op2 = "-"c) Then
Return False
Else
Return True
End If
End Function
' A utility method to apply an operator 'op' on operands 'a'
' and 'b'. Return the result.
Public Function applyOp(op As Char, b As Integer, a As Integer) As Integer
Select Case op
Case "+"c
Return a + b
Case "-"c
Return a - b
Case "*"c
Return a * b
Case "/"c
If b = 0 Then
'Throw New UnsupportedOperationException("Cannot divide by zero")
End If
Return a \ b
End Select
Return 0
End Function
this is how im using the code :
formula = "10 + 2 * 6"
Dim result As Double = evaluate(formula)
and i keep getting this following error:
Unhandled exception at line 885, column 13 in http:**** DEDOM5KzzVKtsL1tWZwgsquruscgqkpS5bZnMu2kotJDD8R38OukKT4TyG0z97U1A8ZC8o0wLOdVNYqHqQLlZ9egcY6AKpKRjQWMa4aBQG1Hz8t_HRmdQ39BUIKoCWPik5bv4Ej6LauiiQptjuzBMLowwYrLGpq6dAhVvZcB-4b-mV24vCqXJ3jbeKi0&t=6119e399
0x800a139e - Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: Conversion from string " " to type 'UInteger' is not valid.
Im a beginner but i think that the error is occurring because its not able to covert space into integer.How to deal with the spaces?? Any help is much appreciated:).
VB.NET is strongly-typed, so you simply cannot push anything other than integers onto a Stack(Of Integer). Therefore this code:
Dim space As String = " "
values.Push(space)
will always fail at runtime. (By the way, you want to set Option Explicit On
and Option Strict On
at the top of every module. If you do that, the line above will already be marked as an error at build time).
I haven't tried executing your code, but why would you need to save the spaces if what you're building is an expression evaluator? It doesn't seem to add anything to the evaluation. Perhaps if you simply don't add the spaces to the stack it will work anyway.