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.rhkb.cn/news/309350.html

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

相关文章

了解 Vue 工程化开发中的组件通信

目录 1. 组件通信语法 1.1. 什么是组件通信? 1.2. 为什么要使用组件通信? 1.3. 组件之间有哪些关系(组件关系分类)? 1.4. 组件通信方案有哪几类 ? 2. 父子通信流程图 3. 父传子 3.1. 父传子核心流程…

Tool:VRAM的简介、查询电脑VRAM的常用方法

Tool:VRAM的简介、查询电脑VRAM的常用方法 目录 VRAM的简介 查询电脑VRAM的常用方法 1、对于Windows系统 T1、设置-系统-显示查询法 T2、使用 DirectX 诊断工具: T3、使用系统信息工具: 2、对于Linux系统 T1、使用nvidia-smi命令&…

网络网络层之(2)ARP协议

网络网络层之(2)ARP协议 Author:Once Day Date: 2024年4月1日 漫漫长路,有人对你笑过嘛… 全系列文档可参考专栏:通信网络技术_Once-Day的博客-CSDN博客。 参考文档: 《TCP/IP详解卷一》arp(8) - Linux manual page (man7.org)彻底搞懂系…

Android MTK 屏下指纹的调试过程记录

Demo链接 -----> https://download.csdn.net/download/u011694328/89118346 一些品牌手机都有了屏下指纹的功能,还算是个比较新颖的功能,最近有项目需要使用屏下指纹, 使用的是汇顶(Goodix)的指纹方案&#xff0c…

<计算机网络自顶向下> TCPUDP套接字编程

应用实现:源端的应用进程交换报文实现应用协议,来实现各种各样的网络应用(dash,email, etc) 而应用层通信不可以直接通信,需要借助下层的服务才可以进行,通过层间接口交给下层,通过…

系统架构最佳实践 -- 金融企业的资损防控

一、资损产生的原因 由于支付行业的特殊性与复杂性(主要处理资金相关业务),支付公司处于资损的风口浪尖,最容易发生资损,可以说资损风险无处不在。 常规来说,资损原因主要可以分为以下三类: 1…

【MATLAB源码-第49期】基于蚁群算法(ACO)算法的栅格路径规划,输出最佳路径图和算法收敛曲线图。

操作环境: MATLAB 2022a 1、算法描述 蚁群算法是一种模拟自然界蚂蚁觅食行为的启发式优化算法。在蚁群系统中,通过模拟蚂蚁之间通过信息素沟通的方式来寻找最短路径。 在栅格路径规划中,蚁群算法的基本步骤如下: 1. 初始化: …

Notepad++软件安装及配置说明

Notepad是 Windows操作系统下的一套文本编辑器,有完整的中文化接口及支持多国语言编写的功能。 Notepad功能比 Windows自带记事本强大,除了可以用来制作一般的纯文字说明文件,也十分适合编写计算机程序代码。Notepad不但可以显示行号&#xf…

鸿蒙开发快速入门

基本概念 ArkTS 因为ArkTS是基于Type Script扩展而来,是Type Script的超集,所以也可以关注一下Type Script的语法来理解ArkTS的语法 ArkUI HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。方舟开发框架…

对常见FTP客户端/服务器的调查与分析

前言 主要是想看看常见的服务器和客户端是如何实现协议中要求的功能的,。 比如RF959要求的记录结构(Record Structure)、页结构(Page Structure)、Block Mode、Compress Mode,看起来就很抽象。 实测发现…

给自己的机器人部件安装单目摄像头并实现gazebo仿真功能

手术执行器添加摄像头 手术执行器文件夹surgical_new内容展示如何添加单目摄像头下载现成的机器人环境文件启动仿真环境 手术执行器文件夹surgical_new内容展示 进入src文件夹下选择进入vision_obliquity文件夹 选择launch 有两个可用gazebo中rviz展示的launch文件&#xff0…

Unity 2D让相机跟随角色移动

相机跟随移动 最简单的方式通过插件Cinemachine 在窗口/包管理器选择全部找到Cinemachine,导入。然后在游戏对象/Cinemachine创建2D Camera。此时层级中创建一个2D相机。选中人物拖入检查器Follow。此时相机跟随人物移动。 修改相机视口距离 在检查器中Lens下调正…

c++11 标准模板(STL)本地化库 - 平面类别(std::codecvt) - 在字符编码间转换,包括 UTF-8、UTF-16、UTF-32 (四)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析,以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 在字符编码间转换,包括 UTF-8、UTF-16、UTF-32 std::…

MES生产管理系统:私有云、公有云与本地化部署的比较分析

随着信息技术的迅猛发展,云计算作为一种新兴的技术服务模式,已经深入渗透到企业的日常运营中。在众多部署方式中,私有云、公有云和本地化部署是三种最为常见的选择。它们各自具有独特的特点和适用场景,并在不同程度上影响着企业的…

python应用-os库操作目录

python自带的os模块提供了许多与操作系统交互的函数,适配多种操作系统,比如windows,mac,linux等,比如常用路径操作、进程管理、环境参数等都可通过os模块实现。 以下是自带的os.py中的前面一部分代码。 第一个红框中主…

kibana源码编译

一、安装nodejs16.14.2及yarn (一)nodejs 1、下载 https://cdn.npmmirror.com/binaries/node/v16.14.2/node-v16.14.2-linux-x64.tar.gz2、解压 tar -zxf node-v16.14.2-linux-x64.tar.gz -C /app cd /app mv node-v16.14.2-linux-x64 node3、配置环…

bugku-web-decrypt

这里的提示解密后没有什么意义 这里下载文件包 得到一个index.php文件 得到代码 <?php function encrypt($data,$key) {$key md5(ISCC);$x 0;$len strlen($data);$klen strlen($key);for ($i0; $i < $len; $i) { if ($x $klen){$x 0;}$char . $key[$x];$x1;}for…

UI设计/交互设计/视觉设计项目汇报/作品集Figma/PPT模板

作为UI设计/交互设计/视觉设计师&#xff0c;创建作品集对于向潜在客户或雇主展示您的技能、创造力和风格至关重要。以下分步指南可帮助您创建令人印象深刻的作品集&#xff1a; 选择您的最佳作品&#xff1a;选择您最强大且最相关的设计项目&#xff0c;将其纳入您的作品集。…

stm32移植嵌入式数据库FlashDB

本次实验的程序链接stm32f103FlashDB嵌入式数据库程序资源-CSDN文库 一、介绍 FlashDB 是一款超轻量级的嵌入式数据库&#xff0c;专注于提供嵌入式产品的数据存储方案。与传统的基于文件系统的数据库不同&#xff0c;FlashDB 结合了 Flash 的特性&#xff0c;具有较强的性能…