问题
I am trying to create a program that parses an expression such as 3x^3 + 7x^2 + 6x - 9. I am using a recursive system to do this. At the moment, I'm just testing to see if I get the correct output for the expression I input by only using constants in the expression. The code works fine with most expressions, but when I have a minus followed by a positive, both terms are subtracted (first term should be subtracted, second term should be added). An example of this is entering 4*3^2-7*3+5*3. The answer to this is 30 but the program does 4*3^2-7*3-5*3 instead and outputs 0. I am unsure how to solve this.
Code:
Private Function ParseExpr(ByRef expression As String)
Dim op, op1 As Integer
op = ParseFactor(expression)
If expression.Length <> 0 Then
If (expression(0) = "+") Then
expression = expression.Substring(1, expression.Length - 1)
op1 = ParseExpr(expression)
op += op1
ElseIf (expression(0) = "-") Then
expression = expression.Substring(1, expression.Length - 1)
op1 = ParseExpr(expression)
op -= op1
End If
End If
Return op
End Function
回答1:
All is well with raising to a power and multiplication. At that point we are simplified to 36-21+15. Here we must remember that we are adding -21. So we need to go back to -7 . When I build my list of numbers (it handles numbers of more than one digit) I add the minus sign to the number it precedes.
This code does not handle decimal numbers or parenthesis. I think you will be able to add the division operator, if you wish.
Private NumList As New List(Of Double)
Private OperatorList As New List(Of String)
Private Sub OpCode()
Dim Input = "14*3^2-7*3+15*3"
PopulateLists(Input)
Dim OpIndex As Integer
Dim NewNum As Double
Dim operators = {"^", "*", "+"} 'Note: no minus sign, the minus goes with the number
For Each op In operators
Do
OpIndex = OperatorList.IndexOf(op)
If OpIndex = -1 Then
Exit Do
End If
Select Case op
Case "^"
NewNum = NumList(OpIndex) ^ NumList(OpIndex + 1)
Case "*"
NewNum = NumList(OpIndex) * NumList(OpIndex + 1)
Case "+"
NewNum = NumList(OpIndex) + NumList(OpIndex + 1)
End Select
NumList.RemoveAt(OpIndex + 1)
NumList(OpIndex) = NewNum
OperatorList.RemoveAt(OpIndex)
Loop
Next
MessageBox.Show(NumList(0).ToString) 'Displays 150
End Sub
Private Sub PopulateLists(Input As String)
Dim strNum As String = ""
For Each c As Char In Input 'Be careful here, the IDE wants to add () at the end of this line - it doesn't belong
If Char.IsDigit(c) Then
strNum &= c
ElseIf c = "-" Then
OperatorList.Add("+") 'We are adding a negative number
NumList.Add(CDbl(strNum)) 'Add the last number we accumulated so we can start a new one with the minus sign
strNum = "-" 'Start a new number with the minus sign
Else 'The other operators are added to the list
OperatorList.Add(c)
NumList.Add(CDbl(strNum))
strNum = ""
End If
Next
NumList.Add(CInt(strNum)) 'The last number which will not be followed by an operator
End Sub
来源:https://stackoverflow.com/questions/65798782/math-expression-parsing-incorrect-output-when-a-followed-by-a