golang 使用栈模拟计算器

思路: 

 

// @Author sunwenbo
// 2024/4/12 16:51
package main

import (
	"errors"
	"fmt"
	"strconv"
)

// 使用数组来模拟一个栈的应用
type Stack struct {
	MaxTop int     //表示栈最大可以存放数的个数
	Top    int     //表示栈底,因为栈底是固定的,因此我们可以直接使用Top
	arr    [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] = val
	return
}

// 遍历栈,需要从栈顶开始遍历
func (this *Stack) List() {
	// 先判断栈是否为空
	if this.Top == -1 {
		fmt.Println("stack  empty")
		return
	}
	//curTop := this.Top
	fmt.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 := 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
}

// 编写一个方法返回某个运算符的优先级[程序员定的]
// [* / => 1, +- = 0 ]
func (this *Stack) Priority(oper int) int {
	res := 0
	if 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,帮助扫描 exp
	index := 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 ==> "+" ==> 43
		temp := 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)
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【QT入门】Qt自定义控件与样式设计之自定义QLineEdit实现搜索编辑框

往期回顾 【QT入门】Qt自定义控件与样式设计之qss的加载方式-CSDN博客 【QT入门】Qt自定义控件与样式设计之控件提升与自定义控件-CSDN博客 【QT入门】Qt自定义控件与样式设计之鼠标相对、绝对位置、窗口位置、控件位置-CSDN博客 【QT入门】Qt自定义控件与样式设计之自定义QLin…

蓝桥杯之注意事项

1.特殊求解的地方 2.一些数学公式 比如二叉树求全深度数值那道题 3.掌握有关库函数 #include<algorithm> 包含sort&#xff08;&#xff09;函数【排列函数】C sort()排序详解-CSDN博客&#xff0c;next_permutation()函数【求解全排列问题】求解数组大小sizeof(arr…

2024年腾讯云最新优惠活动及领券入口整理分享

随着云计算技术的快速发展&#xff0c;越来越多的企业和个人选择将业务部署在云端。腾讯云作为国内知名的云计算服务提供商&#xff0c;为用户提供了丰富的云产品和服务。为了帮助用户降低成本&#xff0c;腾讯云定期推出各种优惠活动。本文将为大家整理分享2024年腾讯云的最新…

亲测能用MathType7破解版本安装包百度网盘下载

MathType 7是一款专业的数学公式编辑工具&#xff0c;广泛应用于教育教学、科研机构、工程学、物理学、化学等多个领域。它支持各种数学符号、公式、方程式、矩阵、分数、上下标等&#xff0c;几乎涵盖了所有的数学元素&#xff0c;可以帮助用户快速、方便地创建高质量的数学公…

【Cesium学习笔记】二、隐藏控件及按钮

【Cesium学习笔记】二、隐藏控件及按钮 一、隐藏控件二、隐藏cesium图标 Ps:本教程所有代码于同一个工程中&#xff0c;运行npm run dev默认首页为App.vue&#xff0c;只需替换App.vue的内容即可切换不同页面。 将上一节的App.vue保存为类似“加载cesium.vue”这种对应名称。 …

如何在Photoshop中,使用本地Stable Diffusion WebUI的绘图能力

&#x1f3c3;‍♂️文章背景 相信设计师朋友们最熟悉的软件应该就是photoshop了&#xff0c;现在AI绘图虽然控制性越来越强&#xff0c;但跟ps比起来&#xff0c;还是要弱很多&#xff0c;尤其是图层、蒙版、笔刷、色调校色等等功能&#xff0c;所以就算是使用SD或者midjourn…

虚拟机下CentOS7开启SSH连接

虚拟机下CentOS7开启SSH连接 自己在VMware中装了CentOS 6.3&#xff0c;然后主机&#xff08;或者说xshell&#xff09;与里面的虚拟机连不通&#xff0c;刚学习&#xff0c;一头雾水&#xff0c;查了半天&#xff0c;也不知道怎么弄。 在虚拟机&#xff08;Vmware Workstatio…

2024蓝桥A组A题

艺术与篮球&#xff08;蓝桥&#xff09; 问题描述格式输入格式输出评测用例规模与约定解析参考程序难度等级 问题描述 格式输入 无 格式输出 一个整数 评测用例规模与约定 无 解析 模拟就好从20000101-20240413每一天计算笔画数是否大于50然后天数&#xff1b; 记得判断平…

Linux 网络排查命令

端口相关服务检查 netstat -ntpl|grep [$Port]说明&#xff1a;[$Port]为相应的端口号。 0.0.0.0代表本机上可用的任意地址。比如&#xff0c;0.0.0.0:80表示本机上所有地址的80端口。 tcp 0.0.0.0:80表示在所有的可用接口上监听TCP的80端口 如果返回结果为空&#xff0c;说明…

rocketmq和rabbitmq总是分不清?

1. 官方解答 摘自百度搜索&#xff1a; 2. 通俗易懂的回答

【Liunx】一键式配置vim,这一篇就够了配图超丰富!

一、配置个性化vim 首先&#xff0c;进入自己的用户中&#xff0c;配置自己的vim时&#xff0c;是不会影响其他用户的。因为有关vim的配置取决于每个用户家目录下的一个配置文件.vimrc 接下来就去我的家目录下看看这个隐藏文件【.vimrc】 打开它&#xff0c;你会发现空空如也…

Vol.46 一个在线小游戏网站,每个月50万访问量

大家好&#xff0c;我是欧维Ove&#xff0c;今天要给大家分享的网站是&#xff1a;小霸王&#xff0c;这是一个可以在线玩小霸王游戏的网站&#xff0c;网址是&#xff1a;小霸王&#xff0c;其樂無窮。紅白機&#xff0c;FC線上遊戲&#xff0c;街機遊戲&#xff0c;街機線上&…

微服务之Consul 注册中心介绍以及搭建

一、微服务概述 1.1单体架构 单体架构&#xff08;monolithic structure&#xff09;&#xff1a;顾名思义&#xff0c;整个项目中所有功能模块都在一个工程中开发&#xff1b;项目部署时需要对所有模块一起编译、打包&#xff1b;项目的架构设计、开发模式都非常简单。 当项…

基于”Python+”多技术融合在蒸散发与植被总初级生产力估算中的应用

熟悉蒸散发ET及其组分&#xff08;植被蒸腾Ec、土壤蒸发Es、冠层截留Ei&#xff09;、植被总初级生产力GPP的概念和碳水耦合的基本原理&#xff1b;掌握利用Python与ArcGIS工具进行课程相关的操作&#xff1b;熟练掌握国际上流行的Penman-Monteith模型&#xff0c;并能够应用该…

网站防御技巧分享

本教程所用到了常接触的 Cloudflare 和宝塔防火墙等工具以下内容均为个人经验和观点&#xff0c;不代表其他人或所谓最佳做法 第一 WAF规则 正确配置防火墙规则可以规避大半可疑请求。 设置一个质询规则是至关重要的&#xff0c;如图所示&#xff1a; 您可以质询安全得分低于3…

电影《你想活出怎样的人生》观后感

上周去看了宫崎骏电影《你想活出怎样的人生》&#xff0c;就像作为导演问观众的一个问题一样&#xff0c;宫崎骏老爷子&#xff0c;在电影中&#xff0c;给出了他的一些开放式答案。自己可是说是宫崎骏的粉丝&#xff0c;宫崎骏老爷子的大部分电影&#xff0c;自己基本都看过了…

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

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

“Plandex:AI编程引擎革新,高效应对复杂任务“

Plandex Plandex 是一个开源的、基于终端的AI编程引擎&#xff0c;用于处理复杂任务。它通过长期运行的代理来完成跨越多个文件和多个步骤的任务&#xff0c;将大型任务分解为更小的子任务&#xff0c;然后逐个实现&#xff0c;直到完成整个工作。这有助于用户处理待办事项、处…

CSS快速入门

目录 一、CSS介绍 1、什么是CSS&#xff1f; ​编辑2、基本语法规范 3、引入方式 4、规范 二、CSS选择器 1、标签选择器 2、类&#xff08;class&#xff09;选择器 3、id选择器 4、通配符选择器 5、复合选择器 三、常用CSS 1、color 2、font-size 3、border 4…

pyqt和opencv结合01:读取图像、显示

在这里插入图片描述 1 、opencv读取图像用于pyqt显示 # image cv2.imread(file_path)image cv2.cvtColor(image, cv2.COLOR_BGR2RGB)# 将图像转换为 Qt 可接受的格式height, width, channel image.shapebytes_per_line 3 * widthq_image QImage(image.data, width, hei…