0

该代码基本上采用数学表达式并对其进行评估。我在 VB.net 中编写的以下代码无耻地取自这里:表达式评估

这是用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

这就是我使用代码的方式:

 formula = "10 + 2 * 6"
                    Dim result As Double = evaluate(formula)

我不断收到以下错误:

Unhandled exception at line 885, column 13 in http: **** DEDOM5KzzVKtsL1tWZwgsquruscgqkpS5bZnMu2kotJDD8R38OukKT4TyG0z97U1A8ZC8o0wLOdVNYqHqQLlZ9egcY6AKpKRjQWMa4aBQG1Hz8t_HRmdQ39BUIKoCWPik5bv4Ej6LauiiQptjuzBMLowwYrLGpq6dAhVvZcB-4b-mV24vCqXJ3jbeKi0&t=6119e399

0x800a139e - Microsoft JScript 运行时错误:Sys.WebForms.PageRequestManagerServerErrorException:从字符串“”到类型“UInteger”的转换无效。

我是初学者,但我认为发生错误是因为它无法将空间转换为整数。如何处理空格?任何帮助深表感谢:)。

4

1 回答 1

1

VB.NET 是强类型的,因此您不能将除整数以外的任何内容推送到 Stack(Of Integer) 上。因此这段代码:

Dim space As String = " "
values.Push(space)

在运行时总是会失败。(顺便说一句,你想在每个模块的顶部设置Option Explicit OnOption Strict On。如果你这样做,上面的行将在构建时被标记为错误)。

我没有尝试执行您的代码,但是如果您正在构建的是表达式评估器,为什么需要保存空格?它似乎没有为评估添加任何内容。也许如果您只是不将空格添加到堆栈中,它无论如何都会起作用。

于 2014-08-08T06:58:18.847 回答