使用栈实现计算器
package main
import (
"fmt"
"strconv"
)
func main() {
expression := "1919+222-22321/222"
numStack := NewArrayStack2(10)
operStack := NewArrayStack2(10)
index := 0
num1 := 0
num2 := 0
oper := rune(0)
res := 0
var ch rune
keepNum := "" //拼接多位数
for index < len(expression) {
ch = rune(expression[index])
if operStack.isOper(ch) { //如果是运算符
if !operStack.isEmpty() { //非空
if operStack.priority(ch) <= operStack.priority(operStack.peak()) {
//如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,
//在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈
num1 = numStack.pop()
num2 = numStack.pop()
oper = rune(operStack.pop())
res = numStack.cal(num1, num2, oper)
//结果入数栈
numStack.push(res)
//当前操作符入符号栈
operStack.push(int(ch))
} else { //当前符号优先级若大于上一个符号,直接入栈
operStack.push(int(ch))
}
} else {
//如果符号栈为空,直接入栈
operStack.push(int(ch))
}
} else {
//如果是数字
keepNum += string(ch)
//如果ch已经是expression的最后一位,就直接入栈
if index == len(expression)-1 {
num, _ := strconv.Atoi(keepNum)
numStack.push(num)
} else {
//判断下一个字符是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈
if operStack.isOper(rune(expression[index+1])) {
num, _ := strconv.Atoi(keepNum)
numStack.push(num)
keepNum = ""
}
}
}
index++
if index >= len(expression) {
break
}
}
for {
if operStack.isEmpty() {
break
}
num1 = numStack.pop()
num2 = numStack.pop()
oper = rune(operStack.pop())
res = numStack.cal(num1, num2, oper)
numStack.push(res)
}
res2 := numStack.pop()
fmt.Printf("表达式 %s = %d", expression, res2)
}
构造函数
type ArrayStack2 struct {
maxsize int
stack []int
top int
}
// NewArrayStack2 构建函数
func NewArrayStack2(maxsize int) *ArrayStack2 {
return &ArrayStack2{
maxsize,
make([]int, maxsize),
-1,
}
}
判断是否空栈
// isEmpty 栈是否为空
func (a *ArrayStack2) isEmpty() bool {
return a.top == -1
}
入栈
// push
func (a *ArrayStack2) push(value int) {
if a.top == a.maxsize-1 {
fmt.Print("栈满无法添加")
return
}
a.top++
a.stack[a.top] = value
}
出栈
// pop
func (a *ArrayStack2) pop() int {
if a.isEmpty() {
panic("栈空无数据")
}
value := a.stack[a.top]
a.top--
return value
}
查看栈顶的元素
// peak
func (a *ArrayStack2) peak() rune {
if a.isEmpty() {
panic("栈空无数据")
}
return rune(a.stack[a.top])
}
打印
// list
func (a *ArrayStack2) list() {
if a.isEmpty() {
panic("栈空")
}
for i, v := range a.stack[:a.top+1] {
fmt.Printf("stack[%d]=%d\n", i, v)
}
}
判断运算符的优先级的方法,以便计算时调用
// priority
func (a ArrayStack2) priority(oper rune) int {
switch oper {
case '*', '/':
return 1
case '+', '-':
return 0
default:
return -1 // 假定目前的表达式只有 +, - , * , /
}
}
判断是否为符号 返回bool值
// isOper
func (a ArrayStack2) isOper(val rune) bool {
return val == '+' || val == '-' || val == '*' || val == '/'
}
下面是计算方法,传入num,oper 传出int类型的结果
使用switch来实现
// cal
func (a ArrayStack2) cal(num1, num2 int, oper rune) int {
res := 0
switch oper {
case '+':
res = num1 + num2
case '-':
res = num2 - num1
case '*':
res = num1 * num2
case '/':
res = num2 / num1
}
return res
}