如何在单个文本框vb.net中获取每个运算符之间的数字

时间:2014-11-05 10:38:32

标签: vb.net

    Dim result As Double
    Dim plus As String()
    Dim Substract As String()
    Dim multiply As String()
    Dim divide As String()
    Dim powerto As String()
    Dim num As Long

    If TextBox1.Text.Contains("^") Then
        powerto = TextBox1.Text.Split("^")
        For Each NumToPower As String In powerto
            result = System.Math.Pow(NumToPower, powerto.Length)
            ' num ^= CStr(NumToPower)
        Next
    End If

    If TextBox1.Text.Contains("/") Then
        divide = TextBox1.Text.Split("/")
        For Each numbertodivide As String In divide
            If numbertodivide <> 0 Then
                num /= CStr(numbertodivide)
                result = num
            Else
                MessageBox.Show("Cannot Divide By 0")
                Exit Sub
            End If
        Next
    End If

    If TextBox1.Text.Contains("*") Then
        multiply = TextBox1.Text.Split("*")
        For Each NumToPower As String In multiply
            num *= CStr(NumToPower)
        Next
        result = num
    End If

    If TextBox1.Text.Contains("+") Then
        plus = TextBox1.Text.Split("+")
        For Each NumToPower As String In plus
            num += CStr(NumToPower)

        Next
        result = num
    End If

    If TextBox1.Text.Contains("-") Then
        Substract = TextBox1.Text.Split("-")
        For Each NumToPower As String In Substract
            num -= CStr(NumToPower)
        Next
        result = num
    End If

    MessageBox.Show(result)

我有一个TextBox,并在其中编写例如&#34; 15 * 2 ^ 3&#34;在计算之前,我怎样才能得到这个等式中的每个数字?

1 个答案:

答案 0 :(得分:0)

Dim input As String = "15*2^35"  
    Dim digits() As String = Regex.Split(input, "[^0-9]+") 
    For Each item As String In digits
        Console.WriteLine(item)
    Next  

但在你的情况下,最好实现tokenizer

您的案例的完整语法是

<exp> ::= <exp> + <term> | <exp> - <term> | <term>
<term> ::= <term> * <power> | <term> / <power> | <power>
<power> ::= <factor> ^ <power> | <factor>
<factor> ::= ( <exp> ) | <int>
<int> ::= <digit> <int> | <digit>
<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

对于简单的方程式" +-*/ and ( ) ",您可以尝试我简单的天真解决方案。请注意,我不擅长解析器或语法因此我使用了简单的就绪语法并删除了左递归。

Simple arithmetic grammar, with left recursion removed, is
expression → factor E’
E’ → + factor E’ | - factor E’ | ε
factor → term F’
F’ → * term F’ | / term F’ | ε
term → digit | ( expression )
digit → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

以下是执行此操作的简单代码:

Module Module1

    Sub Main()

        Dim input() = {"---9+6", "5+6*9+8", "6---9", "15+7*9-(7*9)", "8*9+8*9/3+5", "15*8+5", "15+(8*5)"}
        For Each m As String In input
            Console.WriteLine("{0} -> {1}", m, calculate(m))
        Next
        Dim st = Console.ReadLine()
        Console.WriteLine(calculate(st))
        Console.ReadKey(True)

    End Sub


    Dim numbers As New List(Of Double)

    Public Function calculate(ByVal expression As String) As String
        Try
            numbers.Clear()

            If String.IsNullOrWhiteSpace(expression) Then
                Return ""
            End If 
            Dim index = 0
            Exp(expression, index)

            If numbers.Count > 0 Then
                Return numbers(0).ToString()
            End If
        Catch ex As Exception
            Console.WriteLine(ex.Message)

        End Try
        Return ""
    End Function

    Private Sub Exp(ByVal expression As String, ByRef index As Integer)
        '; E -> FE’ 
        factor(expression, index)
        primeops(expression, index)

    End Sub

    Private Sub primeops(ByVal expression As String, ByRef index As Integer)
        '; E’ -> + F E’ | - F E’ | e
        Select Case getChr(expression, index)

            Case "+"
                index += 1
                '   E() ' -> + F E’  
                factor(expression, index)
                If numbers.Count >= 2 Then
                    Dim at = numbers.Count - 1
                    numbers(at - 1) = numbers(at - 1) + numbers(at)
                    numbers.RemoveAt(at)
                End If
                primeops(expression, index)
            Case "-"
                index += 1
                '   E() ' -> - F E’ 
                factor(expression, index)
                If numbers.Count >= 2 Then
                    Dim at = numbers.Count - 1
                    numbers(at - 1) = numbers(at - 1) - numbers(at)
                    numbers.RemoveAt(at)
                End If
                primeops(expression, index)
            Case ")"
                index += 1
            Case Else
                '; E’ -> e

        End Select
    End Sub
    Private Sub factor(ByVal expression As String, ByRef index As Integer)
        '; F -> TF’
        t(expression, index)
        fprime(expression, index)
    End Sub





    Private Sub fprime(ByVal expression As String, ByRef index As Integer)
        '; F -> * T F’ | / T F’ | e
        Select Case getChr(expression, index)
            Case "*"
                index += 1
                '; F -> * T F’ 
                t(expression, index)

                If numbers.Count >= 2 Then
                    Dim at = numbers.Count - 1
                    numbers(at - 1) = numbers(at - 1) * numbers(at)
                    numbers.RemoveAt(at)
                End If
                fprime(expression, index)
            Case "/"
                index += 1
                '; F ->  / T F’  
                t(expression, index)
                If numbers.Count >= 2 Then
                    Dim at = numbers.Count - 1
                    numbers(at - 1) = numbers(at - 1) / numbers(at)
                    numbers.RemoveAt(at)
                End If
                fprime(expression, index)

            Case ")"
                index += 1
        End Select
        '; F ->  e 
    End Sub



    Private Sub t(ByVal expression As String, ByRef index As Integer)
        'T -> G | (E) 
        number(expression, index)
        brackets(expression, index)
    End Sub


    Private Sub brackets(ByVal expression As String, ByRef index As Integer)
        skipspace(expression, index)
        If getChr(expression, index) = "(" Then
            index += 1
            Exp(expression, index)
        End If
        skipspace(expression, index)
    End Sub

    Private Sub number(ByVal expression As String, ByRef index As Integer)
        'numbers +-[0-9]+.[0-9]+

        skipspace(expression, index)

        Dim sign As Integer = 1
        While True
            If getChr(expression, index) = "+" Then
                index += 1
            ElseIf getChr(expression, index) = "-" Then
                index += 1
                sign = -sign
            Else
                Exit While

            End If

        End While

        Dim m = index
        While Char.IsDigit(getChr(expression, index))
            index += 1
        End While
        If index > m Then
            If getChr(expression, index) = "." Then
                index += 1
                While Char.IsDigit(getChr(expression, index))
                    index += 1
                End While
            End If
            Dim str = expression.Substring(m, index - m)
            numbers.Add(sign * Double.Parse(str)) 
        End If


    End Sub

    Private Sub skipspace(ByVal expression As String, ByRef index As Integer)
        While Char.IsWhiteSpace(getChr(expression, index))
            index += 1
        End While
    End Sub

    Private Function getChr(ByVal Expressions As String, index As Integer) As Char
        If index > Expressions.Length - 1 Then
            Return ""  '
        End If
        Return Expressions(index)

    End Function


End Module

输出:

---9+6 -> -3
5+6*9+8 -> 67
6---9 -> -3
15+7*9-(7*9) -> 15
8*9+8*9/3+5 -> 101
15*8+5 -> 125
15+(8*5) -> 55