入栈及出栈
package main
import (
"errors"
"fmt"
)
//入栈及遍历
//使用数组模拟栈的使用
type Stack struct {
MaxTop int
Top int
arry [5]int
}
//入栈
func (this *Stack) push(val int) {
if this.Top == this.MaxTop-1 {
fmt.Println("stack full")
return
}
this.Top++
this.arry[this.Top] = val
}
//出栈
func (this *Stack) pop() (val int, err error) {
if this.Top == -1 {
fmt.Println("stack empty")
return 0, errors.New("Stack empty")
}
val = this.arry[this.Top]
this.Top--
return val, nil
}
//遍历栈,需要从栈顶开始
func (this *Stack) list() {
if this.Top == -1 {
fmt.Println("stack empty")
return
}
for i := this.Top; i <= 0; i-- {
fmt.Printf("出栈内容:arry[%d]=%v\n", i, this.arry[i])
}
}
func main() {
stack := &Stack{
MaxTop: 5,
Top: -1,
}
stack.push(1)
stack.push(2)
stack.push(3)
stack.list()
}
思路分析:
代码实现:
package main
import (
"errors"
"fmt"
"strconv"
)
type Stack struct {
MaxTop int
Top int
arry [5]int
}
//入栈
func (this *Stack) push(val int) {
if this.Top == this.MaxTop-1 {
fmt.Println("stack full")
return
}
this.Top++
this.arry[this.Top] = val
}
//出栈
func (this *Stack) pop() (val int, err error) {
if this.Top == -1 {
fmt.Println("stack empty")
return 0, errors.New("Stack empty")
}
val = this.arry[this.Top]
this.Top--
return val, nil
}
//遍历栈,需要从栈顶开始
func (this *Stack) list() {
if this.Top == -1 {
fmt.Println("stack empty")
return
}
fmt.Println("栈的情况如下:")
for i := this.Top; i <= 0; i-- {
fmt.Printf("出栈内容:arry[%d]=%v\n", i, this.arry[i])
}
}
//判断一个字符是不是运算符
func (this *Stack) IsOper(val int) bool {
if val == 42 || val == 43 || val == 45 || val == 47 {
return true
} else {
return false
}
}
//运算的方法
func (this *Stack) Cal(num1, num2 int, 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
}
//编写方法,返回运算符的优先级
func (this *Stack) Priority(oper int) int {
res := 0
if oper == 42 || oper == 47 {
res = 1
} else if oper == 43 || oper == 45 {
res = 0
}
return res
}
func main() {
//数据栈
NumStack := &Stack{
MaxTop: 20,
Top: -1,
}
//符号栈
OperStack := &Stack{
MaxTop: 20,
Top: -1,
}
exp := "30+2*6-2"
//定义一个index,帮助扫描exp
index := 0
num1, num2, oper, res := 0, 0, 0, 0
keepNum := ""
for {
ch := exp[index : index+1]
//把字符转换为ASCII码 (+ ====》 43)
temp := int([]byte(ch)[0]) //temp为ascii码值
if OperStack.IsOper(temp) { //是字符
if OperStack.Top == -1 { //空栈
OperStack.push(temp)
} else {
//如果发现operstack栈顶的运算符的优先级 >=当前准备入栈的运算符的优先级,就从符号栈pop出,并从数栈pop出两个数,进行运算,运算后的结果在重新入数栈,
//符号在入符号栈
if OperStack.Priority(OperStack.arry[OperStack.Top]) >= OperStack.Priority(temp) {
num1, _ = NumStack.pop()
num2, _ = NumStack.pop()
oper, _ = OperStack.pop()
res = OperStack.Cal(num1, num2, oper)
//把计算结果重新入数栈
NumStack.push(res)
//当前符号压入符号栈
OperStack.push(temp)
} else { //否则运算符直接入栈
OperStack.push(temp)
}
}
} else { //说明是数
//不能直接传参temp,temp是ASCII码值
//val, _ := strconv.ParseInt(ch, 10, 64)
//NumStack.push(int(val))
//1、处理多位数的思路
//定义一个变量keepNum做拼接
keepNum += ch
//每次都向index后面的字符测试一下,判断是不是运算符,若不是拼接在一起
//如果已经到表达式最后,直接将keepNum入栈
if index == len(exp)-1 {
val, _ := strconv.ParseInt(keepNum, 10, 64)
NumStack.push(int(val))
} else {
//判断index的下一位是不是运算符
if OperStack.IsOper(int([]byte(exp[index+1 : index+2])[0])) {
val, _ := strconv.ParseInt(keepNum, 10, 64)
NumStack.push(int(val))
keepNum = ""
}
}
}
//继续扫描
if index == len(exp)-1 {
break
}
index++
}
//如果扫描表达式完毕,依次从符号栈取出两个数,运算后的结果入数栈,直到符号栈为空
for {
if NumStack.Top == -1 || OperStack.Top == -1 {
break
}
num1, _ = NumStack.pop()
num2, _ = NumStack.pop()
oper, _ = OperStack.pop()
res = OperStack.Cal(num1, num2, oper)
//把计算结果重新入数栈
NumStack.push(res)
}
//如果算法没问题,表达式也正确,则结果就是numstack最后的数
result, _ := NumStack.pop()
fmt.Printf("表达式%s=%v\n", exp, result)
}
参考网站:
https://www.bilibili.com/video/BV114411D768
https://www.bilibili.com/video/BV1hJ411j7gD?p=24
原文:https://www.cnblogs.com/ydg-941020/p/14484840.html