golang数据结构之利用栈求计算表达式(加减乘除)
时间:2022-07-23
本文章向大家介绍golang数据结构之利用栈求计算表达式(加减乘除),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
例如:3+2*6-2
先定义两个栈,一个为数值栈,一个为运算符栈;
stack.go
package stack
import (
"errors"
"fmt"
)
type Stack struct {
MaxTop int //栈最大可以存放的数量
Top int //栈顶
Arr [20]int //模拟栈
}
func (s *Stack) Push(val int) (err error) {
//先判断栈是否满了
if s.Top == s.MaxTop-1 {
fmt.Println("栈满了")
return errors.New("栈满了")
}
s.Top++
s.Arr[s.Top] = val
return
}
func (s *Stack) Pop() (val int, err error) {
if s.Top == -1 {
fmt.Println("栈已空")
return -1, errors.New("栈已空")
}
val = s.Arr[s.Top]
s.Arr[s.Top] = 0
s.Top--
return val, nil
}
func (s *Stack) Show() {
if s.Top == -1 {
fmt.Println("栈为空")
return
}
tmp := s
for i := tmp.Top; i >= 0; i-- {
fmt.Printf("Arr[%d]=%vn", i, tmp.Arr[i])
}
return
}
//判断一个字符是数字还是加减乘除
func (s *Stack) IsOper(val int) bool {
if val == 42 || val == 43 || val == 45 || val == 47 {
return true
} else {
return false
}
}
//运算的方法
func (s *Stack) Cal(num1 int, 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 (s *Stack) Priority(oper int) int {
res := 0
if oper == 42 || oper == 47 {
res = 1
} else if oper == 43 || oper == 45 {
res = 0
}
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: -1,
}
operStack := &stack.Stack{
MaxTop: n,
Top: -1,
}
index := 0
num1 := 0
num2 := 0
oper := 0
result := 0
keepNum := ""
for {
ch := str[index : index+1]
//字符对应的ASCII码值
tmp := int([]byte(ch)[0])
if operStack.IsOper(tmp) {
if operStack.Top == -1 {
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-1 {
val, _ := strconv.ParseInt(keepNum, 10, 64)
numStack.Push(int(val))
} else {
//向index后面探以位
if operStack.IsOper(int([]byte(str[index+1 : index+2])[0])) {
val, _ := strconv.ParseInt(keepNum, 10, 64)
numStack.Push(int(val))
keepNum = ""
}
}
//入栈的数要是int型
// val, _ := strconv.ParseInt(ch, 10, 64)
// numStack.Push(int(val))
}
if index == n-1 {
break
}
//继续扫描
index++
}
//如果表达式扫描完毕,依次取出符号和两位数进行运算
for {
if operStack.Top == -1 {
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 的值是:%vn", str, res)
}
运行结果:
- 理清字符集和字符编码关系
- 我是如何巧妙渗入安全脉搏的(附官方还原详情)
- vscode编写插件详细过程
- zabbix最新SQL注入漏洞+EXP
- 本地密码检索工具 – LaZagne Project
- 我是如何在SQLServer中处理每天四亿三千万记录的
- 程序猿是如何解决SQLServer占CPU100%的
- 记一次SQLServer的分页优化兼谈谈使用Row_Number()分页存在的问题
- 分享一个自制的 .net线程池1
- 分享一个自制的 .net线程池2
- 基于百度翻译的简单爬虫翻译-- coding:utf-8 --访问网址模拟浏览器创建文件夹用一个text文件保存,文件名用单词名字
- .net采集网页方法大全(5种)
- C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
- 中文分词之结巴分词~~~附使用场景+demo(net)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法