下面直接貼出VB代碼,
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 - 1, 1) = "(" 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 - 1, 1) = "(" 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