数据结构之栈
一、入栈
package main
import (
"fmt"
"errors"
)
type Stack struct{
maxTop int
Top int
arr [5]int
}
func (this *Stack) Push(val int)(err error){
if this.Top==this.maxTop-1{
return errors.New("Stack full")
}
this.Top++
this.arr[this.Top]=val
return
}
func (this *Stack) Show(){
if this.Top==-1{
fmt.Println("栈为空...")
return
}
for i:=this.Top;i>-1;i--{
fmt.Printf("arr[%d]=%d\n",i,this.arr[i])
}
}
func main(){
stack:=&Stack{
maxTop:6,
Top:-1,
}
stack.Push(1)
stack.Push(2)
stack.Push(3)
stack.Push(4)
stack.Push(5)
stack.Show()
}
二、出栈
func (this *Stack) Pop()(val int,err error){
if this.Top==-1{
fmt.Println("Stack full")
return
}
val=this.arr[this.Top]
this.Top--
return
}
三、栈实现计算器
计算3+2*6-2
这个算式
首先借鉴上述栈的Pop和Push,这里还需要添加一些底层的函数(判断是否为符号,比较优先级,计算函数)
//设置判断运算符的函数
func (this *Stack) Isoper(val int) bool{
if val==42||val==45||val==43||val==47{
return true
}else{
return false
}
}
//设置计算值的函数
func(this *Stack) cal(num1 int,num2 int,oper int)int{
var res int
switch oper{
case 43:
res=num1+num2
case 45:
res=num1-num2
case 42:
res=num1*num2
case 47:
res=num1/num2
default:
fmt.Println("运算符发生错误")
}
return res
}
//优先级的判断
func (this *Stack) Priority(oper int)int{
var res int
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:="3+2*6-4"
index:=0
num1:=0
num2:=0
res:=0
oper:=0
for{
ch:=exp[index:index+1]
temp:=int([]byte(ch)[0]) //转换为Acall
if operStack.Isoper(temp){ //判断是否为符号
if operStack.Top==-1{ //栈为空
operStack.Push(temp)
}else if operStack.First(operStack.arr[operStack.Top])>=operStack.First(temp){//栈顶元素优先级大于等于输入的
num1,_=numStack.Pop()
num2,_=numStack.Pop()
oper,_=operStack.Pop()
res=operStack.cal(num2,num1,oper)
numStack.Push(res) //计算结果压入
operStack.Push(temp)//将符号压入
}else{
operStack.Push(temp)//将计算结果压入
}
}else{
val,_:=strconv.ParseInt(ch,10,64)
numStack.Push(int(val))
}
if index+1==len(exp){
break
}else{
index++
}
}
for{
num1,_=numStack.Pop()
num2,_=numStack.Pop()
oper,_=operStack.Pop()
res=operStack.cal(num2,num1,oper)
numStack.Push(res)
if operStack.Top==-1{
break
}
}
res,_=numStack.Pop()
fmt.Printf("计算%s的结果为%d",exp,res)
}
由于可能存在30+2*6-2
这种算式,连续两个数字,所以上述的代码只能计算个位数字,需要在判断为数字的时候进行改进
else{
//增加判断是不是连续数字的语句
//设置变量keepNum来累加
keepNum+=ch
//首先判断是否是最后一个数字,如果是,直接Push
if index==len(exp)-1{
val,_:=strconv.ParseInt(keepNum,10,64)
numStack.Push(int(val))
}else{ //判断是否有连续数字
if operStack.Isoper(int([]byte(exp[index+1:index+2])[0])){
val,_:=strconv.ParseInt(keepNum,10,64)
numStack.Push(int(val))
keepNum=""
}
}
}
这样累加后就可以得出多位数的算法
看完这篇文章如果对自己有帮助,请点赞支持,谢谢