目录
介绍
本文通过栈来进行实现综合的计算器,在控制台输入要进行运算的表达式,通过计算将结果输出。
算法思路
- 创建两个栈,numStack栈用于存放表达式中的数字,简称数栈。operStack栈用于存放表达式中的运算符,简称符号栈。
- exp:存储控制台输入的表达式;index:帮助扫描exp表达式。
- 通过扫描exp发现是数字,则直接入数栈numStack
- 如果发现是一个运算符。(1)如果operStack是一个空栈,直接入栈。(2)如果operStack不是一个空栈:1)如果发现operStack栈顶运算符的优先级大于等于当前准备入栈的运算符的优先级,就从符号栈Pop出,并从数栈也Pop两个数进行运算,运算后的结果重新入栈到数栈,符号再入符号栈。2)否则,运算符直接入栈
- 如果扫描表达式完毕,依次从符号栈取出符号,然后从数栈取出两个数,运算后的结果,入数栈,直到符号栈为空。
算法实现
本文运用的栈为:Golang实现数组模拟栈和队列-优快云博客,并在此基础栈中添加一些计算器相关的方法。
判断一个字符是不是运算符
" * "的ASCII码为42;" + "的ASCII码为43; " - "的ASCII码为45; " / "的ASCII码为47;
func (s *Stack) IsOper(val int) bool {
if val == 42 || val == 43 || val == 45 || val == 47 {
return true
} else {
return false
}
}
运算的方法
参数为数栈的两个元素,符号栈对应的ASCII码的符号
func (s *Stack) Cal(num1, num2, oper int) int {
res := 0
switch oper {
case 42:
res = num2 * num1
case 43:
res = num2 + num1
case 45:
res = num2 - num1
case 47:
res = num2 / num1
default:
fmt.Println("运算符错误!")
}
return res
}
运算符的优先级
返回运算符的优先级: * / 优先级为 1; + - 优先级为 0
func (s *Stack) Priority(oper int) int {
if oper == 42 || oper == 47 {
return 1
} else if oper == 43 || oper == 45 {
return 0
}
return 0
}
核心算法
创建数栈和符号栈,定义exp存储表达式。
numStack := &Stack{
MaxTop: 20,
Top: -1,
}
operStack := &Stack{
MaxTop: 20,
Top: -1,
}
var exp string
fmt.Println("请输入一个只包含(+,-,*,/)的表达式")
fmt.Scanln(&exp)
定义num1,num2为数栈要计算的两个数,oper为符号栈的运算符的ASCII码ÿ