数据结构之栈

数据结构之栈

一、入栈

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=""
			  }
		   } 
	   }

这样累加后就可以得出多位数的算法

看完这篇文章如果对自己有帮助,请点赞支持,谢谢

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值