golang数据结构之利用栈求计算表达式(加减乘除)
2024-09-01 23:36:37
例如:3+2*6-2
先定义两个栈,一个为数值栈,一个为运算符栈;
stack.go
package stack import (
"errors"
"fmt"
) type Stack struct {
MaxTop int //栈最大可以存放的数量
Top int //栈顶
Arr []int //模拟栈
} func (s *Stack) Push(val int) (err error) {
//先判断栈是否满了
if s.Top == s.MaxTop- {
fmt.Println("栈满了")
return errors.New("栈满了")
}
s.Top++
s.Arr[s.Top] = val
return
} func (s *Stack) Pop() (val int, err error) {
if s.Top == - {
fmt.Println("栈已空")
return -, errors.New("栈已空")
}
val = s.Arr[s.Top]
s.Arr[s.Top] =
s.Top--
return val, nil } func (s *Stack) Show() {
if s.Top == - {
fmt.Println("栈为空")
return
}
tmp := s
for i := tmp.Top; i >= ; i-- {
fmt.Printf("Arr[%d]=%v\n", i, tmp.Arr[i])
}
return
} //判断一个字符是数字还是加减乘除
func (s *Stack) IsOper(val int) bool {
if val == || val == || val == || val == {
return true
} else {
return false
}
} //运算的方法
func (s *Stack) Cal(num1 int, num2 int, oper int) int {
res :=
switch oper {
//乘法
case :
res = num2 * num1
//加法
case :
res = num2 + num1
//减法
case :
res = num2 - num1
//除法
case :
res = num2 / num1
default:
fmt.Println("运算符错误")
}
return res
} //定义优先级
func (s *Stack) Priority(oper int) int {
res :=
if oper == || oper == {
res =
} else if oper == || oper == {
res =
}
return res
}
main.go
package main import (
"fmt"
"go_code/data_structure/stack"
"strconv"
) func main() { str := "30+2*6-600/2"
n := len(str)
numStack := &stack.Stack{
MaxTop: n,
Top: -,
}
operStack := &stack.Stack{
MaxTop: n,
Top: -,
}
index :=
num1 :=
num2 :=
oper :=
result :=
keepNum := ""
for {
ch := str[index : index+]
//字符对应的ASCII码值
tmp := int([]byte(ch)[])
if operStack.IsOper(tmp) {
if operStack.Top == - {
operStack.Push(tmp)
} else {
//判断栈顶的优先级
if operStack.Priority(operStack.Arr[operStack.Top]) >=
operStack.Priority(tmp) {
num1, _ = numStack.Pop()
num2, _ = numStack.Pop()
oper, _ = operStack.Pop()
result = operStack.Cal(num1, num2, oper)
//将计算的结果重新入栈
numStack.Push(result)
//当前符号重新入栈
operStack.Push(tmp)
} else {
operStack.Push(tmp)
}
} } else {
//判断型如30等数字
keepNum += ch if index == n- {
val, _ := strconv.ParseInt(keepNum, , )
numStack.Push(int(val))
} else {
//向index后面探以位
if operStack.IsOper(int([]byte(str[index+ : index+])[])) {
val, _ := strconv.ParseInt(keepNum, , )
numStack.Push(int(val))
keepNum = ""
}
}
//入栈的数要是int型
// val, _ := strconv.ParseInt(ch, 10, 64)
// numStack.Push(int(val))
}
if index == n- {
break
}
//继续扫描
index++
} //如果表达式扫描完毕,依次取出符号和两位数进行运算
for {
if operStack.Top == - {
break
}
num1, _ = numStack.Pop()
num2, _ = numStack.Pop()
oper, _ = operStack.Pop()
result = operStack.Cal(num1, num2, oper)
//将计算的结果重新入栈
numStack.Push(result)
} res, _ := numStack.Pop()
fmt.Printf("计算表达式 %v 的值是:%v\n", str, res)
}
运行结果:
最新文章
- C/S架构应用程序开发培训笔记
- LeetCode Find All Duplicates in an Array
- newInstance()和new()
- sone2(未完成)
- cocos2dx loading界面 预加载资源 与 资源释放
- 【MVC 4】3.MVC 基本工具(创建示例项目、使用 Ninject)
- 求助 WPF ListViewItem样式问题
- 16g u盘变 成1g u盘 解决方案,使用驱动器中的光盘之前需要将其格式化
- Android学习笔记:TabHost 和 FragmentTabHost(转)
- apache本地和局域网访问设置
- eclipsecdt添加自动补全功能
- java 定义泛型方法
- 设计模式之Chain of Responsibility(职责链)(转)
- 1.5.7、CDH 搭建Hadoop在安装之前(定制安装解决方案---配置单用户模式)
- GO入门——3. 控制语句
- 深入理解JS this,作用域
- 中文分词 coreseek安装笔记
- (一)问候 Log4j 你好
- linux的子进程调用exec( )系列函数
- cookie知识点概述
热门文章
- C#&;.Net干货分享- 构建PrinterHelper直接调用打印机相关操作
- 数据库事务系列-MySQL跨行事务模型
- 手把手教你制作Jlink-OB调试器(含原理图、PCB、外壳、固件)
- (四十三)c#Winform自定义控件-Listview-HZHControls
- VS2019 .Net Core 3.0 Web 项目启用动态编译
- Mybatis1
- (转)阿里 RocketMQ 安装与简介
- 原生PHP网页导出和导入excel文件实例
- git如何合并远程2个分支
- 松软科技web课堂:SQLServer之MIN() 函数