String Equation Solver VB.NET
Hello guys! I have written an equation solver in the past hour, that can solve equations just as good as any, even Google.
For my need, I did not want it to support negative parenthesis such as :
"-(55 + 55)"
But it is easily added. However, it does support equations like these :
I just wrote this inside of a console application, so I could test it and translate it over to the program I am working on. I just decided to share it on MPGH.
Code:
Module LHEquationSolver
Function solveSingle(ByVal equ As String) 'solves equation without parenthesis such as "4-3*4-5/4*7-2+8*12".
Dim fEqu As String = equ.Replace(" ", "")
Dim chars As Char() = fEq*****Array()
If (chars.Length > 0) Then
While chars.Contains("+") Or chars.Contains("-") Or chars.Contains("*") Or chars.Contains("/")
For I As Integer = 1 To chars.Length - 1 Step 1
Dim iChar As Char = chars(I)
If (iChar = "/" Or iChar = "*") Then
Dim subEquStart As Int32 = 0
Dim FirstNumber As Single = 0
Dim SecondNumber As Single = 0
For B As Integer = I - 1 To 0 Step -1 'before */
Dim bChar As Char = chars(B)
If (B = 0) Then
subEquStart = 0
FirstNumber = CSng(fEqu.Substring(0, I))
Exit For
ElseIf (bChar = "+" Or bChar = "-") Then
If (chars(B - 1) = "-" Or chars(B - 1) = "+") Then 'negative number check due to subtraction and negative both using "-".
subEquStart = B
FirstNumber = CSng(fEqu.Substring(B, I - B))
Exit For
Else
subEquStart = B + 1
FirstNumber = CSng(fEqu.Substring(B + 1, I - B - 1))
Exit For
End If
End If
Next
If (I + 2 > chars.Length - 1) Then
SecondNumber = CSng(fEqu.Substring(I + 1, chars.Length - I - 1))
Else
For A As Integer = I + 2 To chars.Length - 1 'after */
Dim aChar As Char = chars(A)
If (A = chars.Length - 1) Then
SecondNumber = CSng(fEqu.Substring(I + 1, chars.Length - I - 1))
Exit For
ElseIf (aChar = "+" Or aChar = "-" Or aChar = "*" Or aChar = "/") Then
SecondNumber = CSng(fEqu.Substring(I + 1, A - I - 1))
Exit For
End If
Next
End If
Dim wholeLength As Byte = (FirstNumber & iChar & SecondNumber).Length
Dim newEqu As String = ""
Select Case iChar
Case "*"
newEqu = fEqu.Substring(0, subEquStart) & (FirstNumber * SecondNumber) & fEqu.Substring(subEquStart + wholeLength)
Case "/"
newEqu = fEqu.Substring(0, subEquStart) & (FirstNumber / SecondNumber) & fEqu.Substring(subEquStart + wholeLength)
End Select
fEqu = newEqu
chars = fEq*****Array()
Exit For
ElseIf (chars.Contains("*") = False And chars.Contains("/") = False) Then
If (iChar = "+" Or iChar = "-") Then
Dim subEquStart As Int32 = 0
Dim FirstNumber As Single = 0
Dim SecondNumber As Single = 0
FirstNumber = CSng(fEqu.Substring(0, I))
If (I + 2 > chars.Length - 1) Then
SecondNumber = CSng(fEqu.Substring(I + 1, chars.Length - I - 1))
Else
For A As Integer = I + 2 To chars.Length - 1 'after */
Dim aChar As Char = chars(A)
If (A = chars.Length - 1) Then
SecondNumber = CSng(fEqu.Substring(I + 1, chars.Length - I - 1))
Exit For
ElseIf (aChar = "+" Or aChar = "-") Then
SecondNumber = CSng(fEqu.Substring(I + 1, A - I - 1))
Exit For
End If
Next
End If
Dim wholeLength As Byte = (FirstNumber & iChar & SecondNumber).Length
Dim newEqu As String = ""
Select Case iChar
Case "+"
newEqu = fEqu.Substring(0, subEquStart) & (FirstNumber + SecondNumber) & fEqu.Substring(subEquStart + wholeLength)
Case "-"
newEqu = fEqu.Substring(0, subEquStart) & (FirstNumber - SecondNumber) & fEqu.Substring(subEquStart + wholeLength)
End Select
fEqu = newEqu
chars = fEq*****Array()
Exit For
ElseIf (I = chars.Length - 1) Then
'equation done but still looping due to subtraction and negative both using "-". Didn't think about this when coming up with method.
Return CSng(fEqu)
End If
End If
Next
End While
Return CSng(fEqu)
End If
Return 0
End Function
Function solveMulti(ByVal equ As String) As Single 'solves equation with parenthesis such as "3+2*5*(10+2-(14+2)/5*(99-12)/5)".
Dim fEqu As String = equ.Replace(" ", "")
Dim chars As Char() = fEq*****Array()
If (chars.Length > 0) Then
While chars.Contains("(")
Dim pLefts As String() = fEqu.Split("(")
Dim selectedEqu As String = pLefts(pLefts.Length - 1)
Dim leftExcess As String = fEqu.Substring(0, fEqu.Length - selectedEqu.Length - 1)
Dim subEquStart As Int32 = leftExcess.Length
selectedEqu = selectedEqu.Split(")")(0)
Dim rightExcess As String = fEqu.Substring(selectedEqu.Length + leftExcess.Length + 2)
Dim result As Single = solveSingle(selectedEqu)
Dim newEqu As String = leftExcess & result & rightExcess
fEqu = newEqu
chars = fEq*****Array()
End While
Return solveSingle(fEqu)
End If
Return 0
End Function
Sub Main()
Console.WriteLine("-5*-4*-3*-2*-1 = " & solveMulti("-5*-4*-3*-2*-1"))
Console.WriteLine("(1*1*-1)-5 = " & solveMulti("(1*1*-1)-5"))
Console.WriteLine("3+2*5*(10+2-(14+2)/5*(99-12)/5) = " & solveMulti("3+2*5*(10+2-(14+2)/5*(99-12)/5)"))
Console.WriteLine("4-3*4-5/4*7-2+8*12 = " & solveMulti("4-3*4-5/4*7-2+8*12"))
Console.ReadKey()
End Sub
End Module
I am using this for a project that allows people that use scratch (scratch.mit.edu), to make windows/linux/mac/and possibly ios/android games. I like to develop things in VB.NET before I go over to java lol.
BTW: I know that its not the most efficient. I should've used a token system, but I don't want to spend too much time on this, since its just a prototype anyways.