中綴表達式轉換成後綴表達式的實現(VB)

在對錶達式求值過程中用到了後綴表達式:
比如: 2+3*(1.5-6*(3-2+4)/3)
其後綴表達式爲:2 3 1.5 6 3 2 – 4 + * 3 / - * +

 下面直接貼出VB代碼,

Option Base 1           ' 讓數組的下標從 1 開始

Dim ptr As String       ' 遍歷源字符串的指針
Dim str As String       ' 無空格字符串
Dim strIndex As Integer ' str迭代量
Dim dstr() As String    ' 存放後綴表達式各字符串
Dim dIndex As Integer   ' dstr() 迭代量
Dim Stack() As String   ' 一個棧,在後綴表達式轉換過程可以用於符號棧,在求值可以存放值
Dim Top As Integer      ' 指向棧頂,初始值爲1
Dim InV As Boolean      ' 判斷是否在一個超過兩位數字的數字內
Dim strlen As Integer   ' dstr, stack的數組維數


'主要程序,用於遍歷源字符串str1
Public Sub mainPro(str1 As String)
    
' 迭代量初始化
    strIndex = 1
    dIndex 
= 0
    Top 
= 1
    InV 
= False
    
str = ""    '切記要將str初始化
        
    str1 
= str1 + "#"       ' 添加結束符"#"
    
    str1 
= Trim(str1)       ' 清除str1兩端的空格
    ptr = Mid(str1, strIndex, 1)
    
    
' 消除str1裏面的空格 ,其實這個初始化過程可以考慮另寫一個函數
    Do While ptr <> "#"
        
If ptr <> " " Then
            
str = str + ptr
        
End If
        
        strIndex 
= strIndex + 1
        ptr 
= Mid(str1, strIndex, 1)
    
Loop
    
    
str = str + "#"
    
    strlen 
= Len(str+ 2       ' 取長度,然後重新定義動態數組
    ReDim dstr(strlen)
    
ReDim Stack(strlen)
    
Call push("#")
    
    strIndex 
= 1
    ptr 
= Mid(str, strIndex, 1)
    
' 判斷str第一個字符是否"+" or "-"
    If ptr = "+" Or ptr = "-" Then
        push (ptr)
        dIndex 
= dIndex + 1
        dstr(dIndex) 
= "0"
        strIndex 
= strIndex + 1
    
End If
    
    
' 開始遍歷str,遇到"#"停止
    Do While ptr <> "#"
        
Select Case ptr
            
Case "0" To "9""."
                
If InV Then
                    dstr(dIndex) 
= dstr(dIndex) + ptr
                
Else
                    dIndex 
= dIndex + 1
                    dstr(dIndex) 
= ptr
                    InV 
= True
                
End If
            
Case "+""-""*""/"
                InV 
= False
                dealop (ptr)
            
Case "("
                
Call push(ptr)
            
Case ")"
                
Call dealclose
              
            
Case Else
                
MsgBox ("表達式出現未知字符")
        
End Select
                
        strIndex 
= strIndex + 1
        ptr 
= Mid(str, strIndex, 1)
    
Loop
    
    
If Top > 1 Then
        
Dim tmp As String
        tmp 
= pop()
        
Do While tmp <> "#"
            dIndex 
= dIndex + 1
            dstr(dIndex) 
= tmp
            tmp 
= pop()
        
Loop
    
End If
    
    dIndex 
= dIndex + 1
    dstr(dIndex) 
= "#"
    
End Sub


Private Sub push(ptr As String)
    
If Top > strlen Then
        
MsgBox ("符號棧上溢出 in push()")
        
End
    
End If
    
    Stack(Top) 
= ptr
    Top 
= Top + 1
End Sub


Private Function pop() As String
    
If Top <= 1 Then
        
MsgBox ("符號棧下溢 in pop()")
        
End
    
End If
    
    Top 
= Top - 1
    pop 
= Stack(Top)
End Function


Private Function getTop() As String
    
If Top <= 1 Then
        
MsgBox ("棧空 in getTop()")
        
End
    
End If
    
    getTop 
= Stack(Top - 1)
End Function


Private Sub dealop(ptr As String)
    
Dim stillIn As Boolean  ' 判斷是否正在處理當前操作符,即當前操作符優先級小於等於符號棧頂的
                            ' 操作符時,應該將棧頂操作符出棧,放到dstr中
    Dim tmp As String       ' 用來存放棧頂元素
    stillIn = True
    
Select Case ptr
        
Case "+"
            
If Mid(str, strIndex - 11= "(" Then
                dIndex 
= dIndex + 1
                dstr(dIndex) 
= "0"
                
Call push(ptr)
            
Else
                
Do While (stillIn)
                    tmp 
= getTop()
                    
Select Case tmp
                        
Case "*""/""-""+"
                            dIndex 
= dIndex + 1
                            dstr(dIndex) 
= pop()
                        
Case "(""#"
                            
Call push(ptr)
                            stillIn 
= False
                        
Case Else
                            
MsgBox ("運算符出錯 in +")
                            
End '結束程序
                    End Select
                
Loop
            
End If
        
        
Case "-"
            
If Mid(str, strIndex - 11= "(" Then
                dIndex 
= dIndex + 1
                dstr(dIndex) 
= "0"
                push (ptr)
            
Else
                
Do While (stillIn)
                    tmp 
= getTop()
                    
Select Case tmp
                        
Case "*""/""+""-"
                            dIndex 
= dIndex + 1
                            dstr(dIndex) 
= pop()
                        
Case "(""#"
                            
Call push(ptr)
                            stillIn 
= False
                        
Case Else
                            
MsgBox ("運算符出錯 in -")
                            
End
                    
End Select
                
Loop
            
End If
            
        
Case "*"
            
Do While (stillIn)
                tmp 
= getTop()
                
Select Case tmp
                    
Case "/""*"
                        dIndex 
= dIndex + 1
                        dstr(dIndex) 
= pop()
                    
Case "(""#""+""-"
                        
Call push(ptr)
                        stillIn 
= False
                    
Case Else
                        
MsgBox ("運算符出錯 in *")
                        
End
                
End Select
            
Loop
            
            
            
Case "/"
                
Do While (stillIn)
                    tmp 
= getTop()
                    
Select Case tmp
                        
Case "*""/"
                            dIndex 
= dIndex + 1
                            dstr(dIndex) 
= pop()
                        
Case "(""#""+""-"
                            
Call push(ptr)
                            stillIn 
= False
                        
Case Else
                            
MsgBox ("運算符出錯 in /")
                            
End
                    
End Select
                
Loop
            
            
Case Else
                
MsgBox ("Error happen in dealop() case else")
                
End
        
End Select
End Sub


Private Sub dealclose()
    
Dim tmp As String  ' 用來存放棧頂元素
    tmp = pop()
    
Do While tmp <> "("
        dIndex 
= dIndex + 1
        dstr(dIndex) 
= tmp
        tmp 
= pop()
    
Loop
    
End Sub


Public Function execute() As String
    
Dim v1 As String, v2 As String, v3 As String   ' 定義運算暫存的變量
    
    dIndex 
= 1
    ptr 
= dstr(dIndex)
    
Do While ptr <> "#"
        
Select Case ptr
            
Case "+"
                v1 
= pop()
                v2 
= pop()
                v3 
= Val(v1) + Val(v2) ' 這裏會將val值隱式轉換成string麼?
                push (v3)
            
            
Case "-"
                v1 
= pop()
                v2 
= pop()
                v3 
= Val(v2) - Val(v1)
                push (v3)
            
            
Case "*"
                v1 
= pop()
                v2 
= pop()
                v3 
= Val(v1) * Val(v2)
                push (v3)
                
            
Case "/"
                v1 
= pop()
                v2 
= pop()
                
If Val(v1) = 0 Then
                    
MsgBox ("式子中除數爲 0 ")
                    
End
                
End If
                v3 
= Val(v2) / Val(v1)
                push (v3)
            
            
Case Else
                push (ptr)
        
End Select
        
        dIndex 
= dIndex + 1
        ptr 
= dstr(dIndex)
    
Loop
    
    v1 
= pop()          '判斷最終結果絕對值是否小於1,如果
    
    
If Abs(Val(v1)) < 1 Then
        v1 
= Format(Val(v1), "0.######")
    
End If
    execute 
= v1
End Function

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章