golang 使用栈模拟计算器

news/2024/5/17 10:29:12

思路: 

 

// @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.mrgr.cn/p/38543242

相关文章

CTF中常见的四种python逆向

pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,pyc 文件是 Python 编译过的字节码文件。它是 Python 程序在运行过程中由源代码(通常是 .py 文件)自动或手动编译产生的二进制文件。说在前面:什么是py…

【笔试训练】day5

今天的题,最后一题忘公式了,卡了一会推出来了 1、游游的you 思路: 看清题目意思就行,这里的相邻两个o可以重复算,也就是说,“ooo”算2分。 先算you的得分,再算oo 对了,不开long lo…

手动给docusaurus添加一个搜索

如果algolia不能自动配置的话,我教你手动给docusaurus添加一个搜索新版博客用docusaurus重构已经有些日子了,根据docusaurus的文档上也申请了Algolia,想一劳永逸的解决博客的搜索问题。但是流水有意,落花无情。 algolia总是不给我回复,我只能对着algolia的申请页面仰天长叹。…

python聊天室

python聊天室 文章目录 python聊天室chat_serverchat_client使用方式1.局域网聊天2.公网聊天 下面是一个简单的示例,包含了chat_client.py和chat_server.py的代码。 chat_server chat_server.py监听指定的端口,并接收来自客户端的消息,并将消…

MercadoLibre(美客多)入仓预约系统操作流程-自动化约号(开篇)

目录 一、添加货件信息 二、输入货件信息 三、选择发货 四、填写交货日期 五、注意事项 MercadoLibre(美客多)于2021年10月18号上线了新预约入仓系统,在MercadoLibre美客多平台上,新入仓预约系统是一项非常重要的功能&#x…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查)

CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查) 文章目录 CTFHUB-技能树-Web前置技能-文件上传(前端验证—文件头检查)前端验证—文件头检查题目解析 各种文件头标志 前端验证—文件头检查 题目考的是:pn…

利用Python进行数据分析 原书第2版 (Wes McKinney)pdf下载

链接:https://pan.baidu.com/s/18MOC0666S-EX_0ks4ivR2g 提取码:rmkk 本书由Python pandas项目创始人Wes McKinney亲笔撰写,详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。第2版针对Python 3.6进行全面修订和更新,涵盖新版的pandas、NumPy…

<计算机网络自顶向下> 多路复用与解复用

多路复用/解复用 端口号区分进程到进程多路解复用工作原理 解复用作用:TCP或者UDP实体采用哪些信息,将报文段的数据部分交给正确的socket,从而交给正确的进程主机收到IP数据报 每个数据报有源IP地址和目标地址每个数据报承载一个传输层报文段…

算法:期望场景;鲁棒优化

部分代码 for i1:T stst[D_DGk(i)*min_P_DG<P_DGk(i)<D_DGk(i)*max_P_DG]; end for i2:T indicatorD_DGk(i)-D_DGk(i-1); rangei:min(T,iT_up-1); st st[D_DGk(range)>indicator]; end for i2:T indicatorD_DGk(i-1)-D_DGk(i); rangei:min(T…

神经网络训练速度相关学习--1

2024-04-18 程序执行的调用顺序: cpu接收到指令,执行——从存储器中加载数据到cpu,对数据进行预处理——预处理后的数据传输gpu——gpu执行运算——将运算结果存储到存储器——开始新一轮batch运算(每一次计算都需要从内存中读取数据) 另外参考:先将硬盘中的数据读取到内…

LeetCode——572—— 另一棵树的子树

1.题目 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/subtree-of-another-tree/ 给你两棵二叉树 root 和 subRoot …

08-接口文档和JWT

接口文档 楔子 接口文档对于协调前后端开发非常重要,可以避免因为开发习惯不同而导致的意外情况。在项目中,如果前后端开发各自为战,可能会出现不一致的情况。因此,接口文档可以约束双方,确保他们按照统一的规范进行开发,从而提高协同开发的效率和一致性。 规范 接口文档…

“趣”学架构

搭系统先搭架子 对于多个业务需求,都有打印入参、检验入参、业务逻辑、打印出参、处理异常的流程。 方法1:做业务逻辑的聚类 但内容经常不同,很难去做大范围的聚类 方法2:模版方法模式 用抽象类做约束,必须实现这些接口伪代码 弊端业务需求会导致代码经常多一个功能,改一…

Spring 源码阅读(一)环境搭建

注意事项:使用 2024-03-14 发布的 Spring 5.3.33 版本 IDE 工具使用了 Intellij IDEA,同时为了简化不必要的内容没单独配置 Gradle 环境 JDK 版本采用 Eclipse Temurin 1.8/11 均可下载源码 下载 SpringFramework 源码,本次选择 5.3.33 版本,发布日期 2024-03-14,通过 Int…

4.18作业

顺序栈&#xff1a; #include "seq_stack.h" seq_p creat_stack() //从堆区申请顺序栈的空间 {seq_p S(seq_p)malloc(sizeof(seq_stack));if(SNULL){printf("空间申请失败\n");return NULL;}bzero(S->data,sizeof(S->data));S->top-1;return S; …

性能测试——性能测试-常见linux性能指标监控命令

vmstat命令: top命令: free -h命令: df -h命令: mpstat命令: sar – 收集和报告系统活动

Apache Zeppelin 命令执行漏洞复现(CVE-2024-31861)

0x01 产品简介 Apache Zeppelin 是一个让交互式数据分析变得可行的基于网页的开源框架&#xff0c;Zeppelin提供了数据分析、数据可视化等功能&#xff0c; 0x02 漏洞概述 Apache Zeppelin 中代码生成控制不当&#xff08;“代码注入”&#xff09;漏洞。攻击者可以使用 She…

这个网络爬虫代码,拿到数据之后如何存到csv文件中去?

大家好,我是皮皮。 一、前言 还是昨天的那个网络爬虫问题,大佬们,帮忙看看这个网络爬虫代码怎么修改?那个粉丝说自己不熟悉pandas,用pandas做的爬虫,虽然简洁,但是自己不习惯,想要在他自己的代码基础上进行修改,获取数据的代码已经写好了,就差存储到csv中去了。 他的…