这段代码是一个简单的中缀表达式转后缀表达式(逆波兰表示法)的计算器,它能够接受用户输入的中缀表达式,转换成后缀表达式,并计算出结果。下面是代码的主要思路和步骤:
-
初始化栈和优先级映射:
stackSymol
和stackNumber
分别用于存储操作符和数字。Priority
映射定义了不同操作符的优先级。
-
字符串到整数的转换:
Atoi
函数用于将字符串转换为整数。
-
中缀转后缀:
transform
函数接收一个中缀表达式字符串,使用正则表达式提取出数字和操作符。- 遍历提取出的元素,根据操作符的优先级和括号的存在,将操作符压入
stackSymol
或弹出到stackNumber
。 - 遇到左括号
(
时,直接压入stackSymol
。 - 遇到右括号
)
时,弹出stackSymol
直到遇到左括号(
,并将弹出的操作符压入stackNumber
。 - 其他情况(数字)直接压入
stackNumber
。
-
计算后缀表达式:
sum1
函数遍历stackNumber
,将数字压入slience
栈。- 遇到操作符时,从
slience
栈中弹出两个数字,执行相应的操作,并将结果压回slience
栈。 - 特别注意除法操作时,需要检查除数是否为零,避免除零错误。
-
主函数:
main
函数负责接收用户输入的中缀表达式,调用transform
函数进行转换,然后调用sum1
函数计算结果,并输出。
代码
package main
import (
"fmt"
"regexp"
"strconv"
)
var stackSymol []string
var stackNumber []string
var Priority = map[string]int{
"+": 1,
"-": 1,
"*": 2,
"/": 2,
}
// 定义一个函数,将字符串转化为int
func Atoi(fu string) int {
i, _ := strconv.Atoi(fu)
return i
}
// 定义一个函数,将中缀转为后缀
func transform(formual string) {
//正则表达式将符号数字取出
re := regexp.MustCompile(`(\d+\.\d+|\d+|\+|-|\*|\/|\(|\))`)
matches := re.FindAllString(formual, -1)
for _, m := range matches {
switch m {
case "+", "-", "*", "/":
if len(stackSymol) == 0 || stackSymol[len(stackSymol)-1] == "(" || Priority[m] >= Priority[stackSymol[len(stackSymol)-1]] {
stackSymol = append(stackSymol, m)
} else if len(stackSymol) != 0 && stackSymol[len(stackSymol)-1] != "(" && Priority[m] < Priority[stackSymol[len(stackSymol)-1]] {
stackNumber = append(stackNumber, stackSymol[len(stackSymol)-1])
stackSymol = stackSymol[:len(stackSymol)-1]
stackSymol = append(stackSymol, m)
}
case "(":
stackSymol = append(stackSymol, m)
case ")":
for stackSymol[len(stackSymol)-1] != "(" {
stackNumber = append(stackNumber, stackSymol[len(stackSymol)-1])
stackSymol = stackSymol[:len(stackSymol)-1]
}
stackSymol = stackSymol[:len(stackSymol)-1]//去除“(”
default:
stackNumber = append(stackNumber, m)
}
}
//将stackSymol中全部转入stackNumber
for len(stackSymol) > 0 {
stackNumber = append(stackNumber, stackSymol[len(stackSymol)-1])
stackSymol = stackSymol[:len(stackSymol)-1]
}
}
//进行计算,返回最终值
func sum1() int {
var slience = make([]int, 0)
for _, v := range stackNumber {
//判断v是否为数字
if _, err := strconv.Atoi(v); err == nil {
slience = append(slience, Atoi(v))
} else {
right := slience[len(slience)-1]
slience = slience[:len(slience)-1]
left := slience[len(slience)-1]
slience = slience[:len(slience)-1]
switch v {
case "+":
slience = append(slience, right+left)
case "-":
slience = append(slience, right-left)
case "*":
slience = append(slience, right*left)
case "/":
if right == 0 {
panic("dont zero")
}
slience = append(slience, left/right)
}
}
}
return slience[0]//返回最终值
}
func main() {
var formula string
fmt.Printf("输入一个算式")
fmt.Scan(&formula)
transform(formula)
ra := sum1()
fmt.Println(ra)
}