golang数据结构之利用栈求计算表达式(加减乘除)
例如: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)
}
运行结果:
golang数据结构之利用栈求计算表达式(加减乘除)的更多相关文章
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- K:双栈法求算术表达式的值
相关介绍: 该算法用于求得一个字符串形式的表达式的结果.例如,计算1+1+(3-1)*3-(21-20)/2所得的表达式的值,该算法利用了两个栈来计算表达式的值,为此,称为双栈法,其实现简单且易于理 ...
- SDUT 2133 数据结构实验之栈三:后缀式求值
数据结构实验之栈三:后缀式求值 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 对于一个基于二元运算符的后缀表示式(基本操作数都是 ...
- 河南省acm第九届省赛--《表达式求值》--栈和后缀表达式的变形--手速题
表达式求值 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 假设表达式定义为:1. 一个十进制的正整数 X 是一个表达式.2. 如果 X 和 Y 是 表达式,则 X+Y, ...
- SDUT-2133_数据结构实验之栈与队列三:后缀式求值
数据结构实验之栈与队列三:后缀式求值 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运算符的后缀表示式 ...
- SDUT-2132_数据结构实验之栈与队列二:一般算术表达式转换成后缀式
数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运 ...
- 中缀表达式转后缀表达式(用于求字符串表达式值)(js栈和队列的实现是通过数组的push和unshift方法插值,pop方法取值)
中缀表达式:就是我通常用的算术或逻辑公式: 后缀表达式:不包含括号,运算符放在两个运算对象后面,所有的计算按运算符出现的顺序,严格从左向右进行,不用考虑运算符优先级: 如,(2+1)*3 转换后,2 ...
- 紫书 习题7-13 UVa 817(dfs+栈求表达式的值)
题目链接 点击打开链接 这道题分为两个部分, 一用搜索枚举每种可能, 二计算表达式的值, 有挺多细节需要注意 特别注意我的代码中在计算表达式的值中用到了一个!(代码枚举中的!表示不加符号, 我现在说 ...
- 6, java数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式
直接上代码: public class PolandCalculator { //栈的应用:波兰计算器: 即: 输入一个字符串,来计算结果, 比如 1+((2+3)×4)-5 结果为16 public ...
随机推荐
- 团队项目之Scrum5
小组:BLACK PANDA 时间:2019.11.25 每天举行站立式会议 提供当天站立式会议照片一张 2 昨天已完成的工作 2 实现文章展示页面 完善后台的编辑功能接口 今天计划完成的工作 2 ...
- 如何计算Data Guard环境中Redo所需的网络带宽传输 (Doc ID 736755.1)
How To Calculate The Required Network Bandwidth Transfer Of Redo In Data Guard Environments (Doc ID ...
- 一次在CentOS系统单用户模式下使用passwd命令破密失败的案例
某次遇到需要进入系统的单用户模式进行破密操作,结果却显示如下: 根据提示:Permission denied(缺少权限) 此时查看/usr/bin/passwd 权限: 正常情况下的权限应该是如下: ...
- 截取字符串substr和substring两者的区别
两者有相同点: 如果只是写一个参数,两者的作用都是一样的:就是截取字符串当前下标以后直到字符串最后的字符串片段. 不同点:第二个参数: substr(startIndex,lenth): 第二个参数是 ...
- Django中的sql注入
Django中防止SQL注入的方法 方案一总是使用Django自带的数据库API.它会根据你所使用的数据库服务器(例如PostSQL或者MySQL)的转换规则,自动转义特殊的SQL参数.这被运用到了整 ...
- Latex学习与使用
Table of Contents Latex学习与使用 简介 文档结构 排版 表格 图片 公式 索引 简介 Latex(发音lay-tek)是一个用来产生专业文档的系统,但它并不是一个单词处理器.它 ...
- Java变量在内存中的存储
目录 Java变量在内存中的存储 成员变量 局部变量 总结 Java变量在内存中的存储 以下探究成员变量和局部变量在内存中的存储情况. package com.my.pac04; /** * @aut ...
- 随机的标识符GUID
Guid guid = Guid.NewGuid();Console.WriteLine(guid.ToString());
- (转)GitHub Desktop 拉取 GitHub上 Tag 版本代码
转自:GitHub Desktop 拉取 GitHub上 Tag 版本代码 一直在使用 GitHub Desktop 图形化 git 管理工具,统一项目框架版本时需要切换到ThinkPHP Tag 分 ...
- linux中网络配置
一.查看ip ipconfig 二.png 测试主机之间网络连通 ping 目标ip #测试当前服务器是否可以连接目的主机 三.linux配置网络环境 vim /etc/sysconfig/netwo ...