golang 使用栈模拟计算器

思路: 

 

// @Author sunwenbo
// 2024/4/12 16:51
package mainimport ("errors""fmt""strconv"
)// 使用数组来模拟一个栈的应用
type Stack struct {MaxTop int     //表示栈最大可以存放数的个数Top    int     //表示栈底,因为栈底是固定的,因此我们可以直接使用Toparr    [20]int //数组模拟栈
}// 入栈
func (this *Stack) Push(val int) (err error) {// 先判断栈是否已经满了if this.Top == this.MaxTop-1 {fmt.Println("stack full")return errors.New("stack full")}this.Top++// 放入数据this.arr[this.Top] = valreturn
}// 遍历栈,需要从栈顶开始遍历
func (this *Stack) List() {// 先判断栈是否为空if this.Top == -1 {fmt.Println("stack  empty")return}//curTop := this.Topfmt.Println("栈的情况如下:")for i := this.Top; i >= 0; i-- {fmt.Printf("arr[%d]=%d\n", i, this.arr[i])}
}// 出栈
func (this *Stack) Pop() (val int, err error) {// 判断栈是否为空if this.Top == -1 {fmt.Println("stack empty")return 0, errors.New("stack empty")}// 先取值,再this.Top--val = this.arr[this.Top]this.Top--return val, nil
}// 判断一个字符是不是一个运算符 [+,-,*,/]
func (this *Stack) IsOper(val int) bool {if val == 42 || val == 43 || val == 45 || val == 47 {return true} else {return false}}// 运算的方法
func (this *Stack) Cal(num1 int, num2 int, oper int) int {res := 0switch oper {case 42:res = num2 * num1case 43:res = num2 + num1case 45:res = num2 - num1case 47:res = num2 / num1default:fmt.Println("运算符错误..")}return res
}// 编写一个方法返回某个运算符的优先级[程序员定的]
// [* / => 1, +- = 0 ]
func (this *Stack) Priority(oper int) int {res := 0if oper == 42 || oper == 47 {return 1} else if oper == 44 || oper == 45 {fmt.Println("oper=", oper)return 0}return res
}func main() {// 数栈numStack := &Stack{MaxTop: 20,Top:    -1}// 符号栈operStack := &Stack{MaxTop: 20,Top:    -1}exp := "30+3*6-4"// 定义一个index,帮助扫描 expindex := 0// 为了配合运算,我们定义需要的变量num1, num2, oper, result, keepNum := 0, 0, 0, 0, ""for {fmt.Println("numStack")numStack.List()fmt.Println("operStack")operStack.List()// 这里需要增加一个逻辑,处理多位数的问题ch := exp[index : index+1] // 字符串// ch ==> "+" ==> 43temp := int([]byte(ch)[0])  // 字符对应的ASCI码if operStack.IsOper(temp) { //说明是符号//如果operStack 是一个空栈,直接入栈if operStack.Top == -1 { // 空栈operStack.Push(temp)} else {// 两个逻辑// 1. 如果发现operStack 栈顶的运算符的优先级大于等于当前准备入栈的运算符的优先级,就从符号栈Pop出,//并从数栈也pop两个数,进行运算,运算后的结果再重新入栈到栈,符号再入符号栈if operStack.Priority(operStack.arr[operStack.Top]) >= operStack.Priority(temp) {num1, _ = numStack.Pop()num2, _ = numStack.Pop()oper, _ = operStack.Pop()result = operStack.Cal(num1, num2, oper)// 将计算结果重新入数栈numStack.Push(result)// 将当前的符号压入符号栈operStack.Push(temp)} else {operStack.Push(temp)}}} else { //说明是数字//处理多位数的思路// 1. 先定义一个变量keepNum string,做拼接工作keepNum += ch// 2. 每次要向index的后面字符测试一下,看看是不是运算符,然后再做处理// 如果到表达式的最后了,直接将keepNum 转换成整数if index == len(exp)-1 { // 已经到表达式最后了val, _ := strconv.ParseInt(keepNum, 10, 64)numStack.Push(int(val))} else {// index 的后一位测试一下,看看是不是运算符,如果不是运算符则继续上面的for循环,做字符串拼接if operStack.IsOper(int([]byte(exp[index+1 : index+2])[0])) {val, _ := strconv.ParseInt(keepNum, 10, 64)numStack.Push(int(val))keepNum = ""}}//val, _ := strconv.ParseInt(ch, 10, 64)//numStack.Push(int(val))}// 继续扫描,先判断index 是否已经扫描到计算表达式的最后if index+1 == len(exp) {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)}// 如果我们的算法没有问题,表达式也是正确的则结果就是numStack的最后一个数res, _ := numStack.Pop()fmt.Printf("表达式: %s=%v", exp, res)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/619477.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【方法】如何打开ZIP分卷压缩文件?

ZIP分卷压缩文件,是指在压缩文件时,将文件压缩成若干个ZIP格式的小压缩包,便于储存和传送,这些小压缩包可以被当作一个完整的文件来处理。那ZIP分卷压缩文件要怎么打开呢?不清楚的小伙伴一起来看看吧! 首先…

星邦生化设备有限公司将出席2024第13届生物发酵展

参展企业介绍 宁波星邦生化设备有限公司,致力于发酵空气处理、发酵尾气处理及发酵罐节能环保装备的研发制造达30余年。公司拥有20多项自主开发的具有竞争力的国家发明专利技术及核心专有技术。连续三届被中国生物发酵产业协会评为——节能环保重点推荐企业。公司用…

LeetCode 678——有效的括号字符串

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 需要两个栈,一个用来保存左括号所在的位置索引,一个用来保存星号所在的位置索引。 从左往右遍历字符串,如果是左括号或者星号,则将位置索引分别入栈,如…

碧桂园服务:政企联合,助力秭归脐橙销售

4月9日,秭归县农业农村局与碧桂园服务智享楼下心选签订了秭归伦晚脐橙助农合作项目。 秭归县农业农村局现场对接碧桂园服务集团智享心选全国十二个重点区域核心业主代表,并授予他们“秭归伦晚脐橙推广大使”证书,每位代表都变成了秭归伦晚脐橙…

【Next】动态路由、加载 UI 和流式传输

动态路由 动态段作为 params 属性传递给 layout、page、route 和 generateMetadata 函数。 /app/blog/[slug]/page.tsx export default function Page({params}: {params:{slug:string}}) {return <h1>Slug Page -- {params.slug}</h1> };/app/shop/[...slug]/pa…

Chatgpt掘金之旅—有爱AI商业实战篇|播客剧本写作|(十三)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业播客剧本写作服务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。…

Scaffold-GS 代码阅读笔记

1. 系统启动部分 使用 python 中的 parser 库 为配置系统的参数设定, 和3DGS 类似&#xff0c;并且使用safe_state(args.quiet) 函数 为每一次的 log 输出加上对应的 时间戳 ## 配置参数的设定lp ModelParams(parser)op OptimizationParams(parser)pp PipelineParams(pars…

面试经典算法系列之二叉数6 -- 二叉树的右视图

面试经典算法21 - 二叉树的右视图 LeetCode.199 公众号&#xff1a;阿Q技术站 问题描述 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4]…

数字乡村创新实践探索农业现代化与乡村振兴新路径:科技赋能农村全面振兴与农民幸福新篇章

随着信息技术的飞速发展&#xff0c;数字乡村成为推动农业现代化与乡村振兴的重要战略举措。科技赋能下的数字乡村创新实践&#xff0c;不仅提升了农业生产的智能化水平&#xff0c;也为乡村治理和农民生活带来了翻天覆地的变化。本文旨在探讨数字乡村创新实践在农业现代化与乡…

80% 的人都不会的 15 个 Linux 实用技巧

熟悉 Linux 系统的同学都知道&#xff0c;它高效主要体现在命令行。通过命令行&#xff0c;可以将很多简单的命令&#xff0c;通过自由的组合&#xff0c;得到非常强大的功能。 命令行也就意味着可以自动化&#xff0c;自动化会使你的工作更高效&#xff0c;释放很多手工操作&…

【周总结】

周总结 完成工单脚本的编写以及解决操作问题 完成相关 jira 问题修改 学习了 sentinel 整合项目使用流控&#xff0c;熔断&#xff0c;热点等功能的使用 2024/4/14 晴 1. 这周只办两件事&#xff0c;吃&#xff01;喝&#xff01;&#xff01;&#xff01; 2.忙忙忙&am…

978: 输出利用先序遍历创建的二叉树的中序遍历序列

解法&#xff1a; #include<iostream> #include<queue> using namespace std; // 定义二叉树结点 struct TreeNode {char val;TreeNode* left;TreeNode* right;TreeNode(char x) :val(x), left(NULL), right(NULL) {}; }; // 先序递归遍历建立二叉树 TreeNode* bu…