后缀表达式的评估
在本教程中,我们将评估一个后缀表达式。
算法:
-
从左到右扫描后缀表达式。
-
如果当前扫描到的字符是一个操作数,则将其推入堆栈。
-
如果当前扫描的字符是一个操作数,那么从堆栈中弹出两个操作数。在弹出的两个操作数上评估运算符,并将结果推入堆栈。
-
当后缀表达式被完全扫描后,堆栈中应该只有一个值,这就是后缀表达式的结果。
实现方法
下面是golang中Infix到Postfix转换的实现。
package main
import (
"fmt"
"math"
"strconv"
)
type Stack []int
//IsEmpty: check if stack is empty
func (st *Stack) IsEmpty() bool {
return len(*st) == 0
}
//Push a new value onto the stack
func (st *Stack) Push(data int) {
*st = append(*st, data) //Simply append the new value to the end of the stack
//fmt.Println("st after push", st)
}
//Remove top element of stack. Return false if stack is empty.
func (st *Stack) Pop() bool {
if st.IsEmpty() {
return false
} else {
index := len(*st) - 1 // Get the index of top most element.
*st = (*st)[:index] // Remove it from the stack by slicing it off.
//fmt.Println("st after pops", *st)
return true
}
}
//Return top element of stack. Return false if stack is empty.
func (st *Stack) Top() int {
if st.IsEmpty() {
return 0
} else {
index := len(*st) - 1 // Get the index of top most element.
element := (*st)[index] // Index onto the slice and obtain the element.
return element
}
}
//function to evaluate postfix expression
func evaluationPostfix(postfix string) int {
var intStack Stack
for _, char := range postfix {
opchar := string(char)
//fmt.Println(opchar)
if opchar >= "0" && opchar <= "9" {
i1, _ := strconv.Atoi(opchar)
//fmt.Println("Integer value is: ", i1)
intStack.Push(i1)
//fmt.Println(intStack)
} else {
opr1 := intStack.Top()
intStack.Pop()
opr2 := intStack.Top()
intStack.Pop()
switch char {
case '^':
x := math.Pow(float64(opr2), float64(opr1))
intStack.Push(int(x))
case '+':
intStack.Push(opr2 + opr1)
case '-':
intStack.Push(opr2 - opr1)
case '*':
intStack.Push(opr2 * opr1)
case '/':
intStack.Push(opr2 / opr1)
}
}
}
return intStack.Top()
}
func main() {
postfix := "2323^5-212*+^*+4-"
evaluationReslt := evaluationPostfix(postfix)
fmt.Printf("evaluation of %s is %d", postfix, evaluationReslt)
}
输出。
2+3*(2^3-5)^(2+1*2)-4 infix has 2323^5-212*+^*+4- postfix
我们可以通过在Push和Pop函数声明中取消对fmt.Println行的注释来检查每次推送和弹出操作后堆栈的状态。