【C++】表达式求值

文章目录

  • 算法思想
  • 代码实现


算法思想

这是对栈的应用,对于中缀表达式求值,需要定义两个栈:数字栈和符号栈,顾名思义分别存放数字和符号。

  1. 遇到数字,直接入数字栈,需要注意并不是只有个位数,还是需要一定的处理,详情见代码。
  2. 遇到符号,有三种情况:
  • 左括号(:直接入符号栈。
  • 右括号):取两个数字栈的数据,取一个符号栈的数据,计算结果放入数字栈,循环直到符号栈中取出(结束。
  • +-*/运算符:符号栈为空,直接入符号栈,不为空则需要比较当前的运算符符号栈栈顶元素的优先级,当栈顶元素优先级大于等于当前的运算符,符号栈出栈,取两个数字栈元素进行计算,结果放入数字栈,循环,将所有大于等于当前的运算符的全部出栈为止。
  1. 最后的计算结果为数字栈的栈顶元素。

提前使用map集合定义好优先级


代码实现

#include <iostream>
#include <string>
#include <stack>
#include <map>

using namespace std;

// 表达式求值 1+2*3/4*(5-6)

int main() {
	string str; // 表达式
	stack<int> num; // 数字栈
	stack<char> ch; // 符号栈
	
	// 定义好运算符的优先级 括号优先级为 0 
	map<char, int> m;
	m['+'] = 1;
	m['-'] = 1;
	m['/'] = 2;
	m['*'] = 2;
	m['('] = 0;
	m[')'] = 0;

	int a, b, i, sum;


	while (cin >> str) 
	{
		
		i = 0;
		while (i < str.size())
		{
			// 遇到数字 直接入栈
			if (str[i] <= '9' && str[i] >= '0') {
				sum = 0;
				while (str[i] <= '9' && str[i] >= '0') {
					sum = sum * 10 + (str[i] - '0');
					i++;
				}
				num.push(sum);
			}
			else
			{
				// 遇到符号

				// 左括号 直接入栈
				if (str[i] == '(') {
					ch.push(str[i]);
				}
				else if (str[i] == ')')
				{
					// 右括号: 符号位要一直出栈,直到, 第一个(出现
					while (ch.top() != '(') {
						a = num.top();
						num.pop();
						b = num.top();
						num.pop();
						switch (ch.top())
						{
						case('+'): a = a + b; break;
						case('-'): a = b - a; break;
						case('*'): a = a * b; break;
						case('/'): a = b / a; break;
						default:
							break;
						}
						num.push(a);
						ch.pop();
					}
					ch.pop(); // 左括号弹出
				}
				else
				{
					// 运算符 : 比较优先级 大于等于-》出栈计算 (循环)
					while ( !ch.empty() && m[ch.top()] >= m[str[i]]) {
						a = num.top();
						num.pop();
						b = num.top();
						num.pop();
						switch (ch.top())
						{
						case('+'): a = a + b; break;
						case('-'): a = b - a; break;
						case('*'): a = a * b; break;
						case('/'): a = b / a; break;
						default:
							break;
						}
						num.push(a);
						ch.pop();
					}
					ch.push(str[i]);

				}

				i++;
				
			}
		}

		while (!ch.empty()) {
			a = num.top();
			num.pop();
			b = num.top();
			num.pop();
			switch (ch.top())
			{
			case('+'): a = a + b; break;
			case('-'): a = b - a; break;
			case('*'): a = a * b; break;
			case('/'): a = b / a; break;
			default:
				break;
			}
			num.push(a);
			ch.pop();
		}

		cout << num.top() << endl;
	}

	return 0;
}

上面代码有一段多次重复的代码,最好重构一下,单独拿出来封装成一个方法。

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

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

相关文章

【经验总结】10年的嵌入式开发老手,到底是如何快速学习和使用RT-Thread的?(文末赠书5本)

【经验总结】一位近10年的嵌入式开发老手&#xff0c;到底是如何快速学习和使用RT-Thread的&#xff1f; RT-Thread绝对可以称得上国内优秀且排名靠前的操作系统&#xff0c;在嵌入式IoT领域一直享有盛名。近些年&#xff0c;物联网产业的大热&#xff0c;更是直接将RT-Thread这…

python绘制图像中心坐标二维分布曲线

数据和代码如下所示&#xff1a; import pandas as pd import numpy as np import matplotlib.pyplot as plt import xlrd from scipy.stats import multivariate_normal from mpl_toolkits.mplot3d import Axes3D np.set_printoptions(suppressTrue)# 根据均值、标准差,求指定…

SuperMap iMobile for Android 地图开发(一)

第一步&#xff1a;创建 Android Studio 项目 第一步&#xff1a;创建 Android Studio 项目 Android Studio 有两种创建项目的方法。 第一种是在 Android Studio起始页选择“Start a new Android Studio Project”。 第二种是在 Android Studio 主页选择“File”–>“New P…

数仓建模—主题域和主题

主题域和主题 前面在这个专题的第一篇,也就是数仓建模—数仓初识中我们就提到了一个概念—主题,这个概念其实在数仓的定义中也有提到 数据仓库是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策。 今天我们主要来探究一下,数仓的主题到底是…

Multi-Camera Color Correction via Hybrid Histogram Matching直方图映射

文章目录Multi-Camera Color Correction via Hybrid Histogram Matching1. 计算直方图&#xff0c; 累计直方图&#xff0c; 直方图均衡化2. 直方图规定化&#xff0c;直方图映射。3. 实验环节3.1 输入图像3.2 均衡化效果3.3 映射效果4. 针对3实验环节的伪影 做处理和优化&…

ChatGPT研究分析:GPT-4做了什么

前脚刚研究了一轮GPT3.5&#xff0c;OpenAI很快就升级了GPT-4&#xff0c;整体表现有进一步提升。追赶一下潮流&#xff0c;研究研究GPT-4干了啥。本文内容全部源于对OpenAI公开的技术报告的解读&#xff0c;通篇以PR效果为主&#xff0c;实际内容不多。主要强调的工作&#xf…

九种跨域方式实现原理(完整版)

前言 前后端数据交互经常会碰到请求跨域&#xff0c;什么是跨域&#xff0c;以及有哪几种跨域方式&#xff0c;这是本文要探讨的内容。 一、什么是跨域&#xff1f; 1.什么是同源策略及其限制内容&#xff1f; 同源策略是一种约定&#xff0c;它是浏览器最核心也最基本的安…

如何发布自己的npm包

一、什么是npm npm是随同nodejs一起安装的javascript包管理工具&#xff0c;能解决nodejs代码部署上的很多问题&#xff0c;常见的使用场景有以下几种&#xff1a; ①.允许用户从npm服务器下载别人编写的第三方包到本地使用。 ②.允许用户从npm服务器下载并安装别人编写的命令…

K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示

K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCMQ2传感参模块1.2、STM32F103C8T6MQ2传感参模块五、基础知识学习与相关…

Vue3之插槽(Slot)

何为插槽 我们都知道在父子组件间可以通过v-bind,v-model搭配props 的方式传递值&#xff0c;但是我们传递的值都是以一些数字&#xff0c;字符串为主&#xff0c;但是假如我们要传递一个div或者其他的dom元素甚至是组件&#xff0c;那v-bind和v-model搭配props的方式就行不通…

让你少写多做的 ES6 技巧

Array.of 关于奇怪的 Array 函数&#xff1a; 众所周知&#xff0c;我们可以通过Array函数来做以下事情。 初始化一个指定长度的数组。 设置数组的初始值。 // 1. Initialize an array of the specified length const array1 Array(3) // [ , , ] // 2. Set the initial value…

Spring Cloud学习笔记【负载均衡-Ribbon】

文章目录什么是Spring Cloud RibbonLB&#xff08;负载均衡&#xff09;是什么Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别&#xff1f;Ribbon架构工作流程Ribbon Demo搭建IRule规则Ribbon负载均衡轮询算法的原理配置自定义IRule新建MyRuleConfig配置类启动类添加Rib…

SQLMap 源码阅读

0x01 前言 还是代码功底太差&#xff0c;所以想尝试阅读 sqlmap 源码一下&#xff0c;并且自己用 golang 重构&#xff0c;到后面会进行 ysoserial 的改写&#xff1b;以及 xray 的重构&#xff0c;当然那个应该会很多参考 cel-go 项目 0x02 环境准备 sqlmap 的项目地址&…

学习java——②面向对象的三大特征

目录 面向对象的三大基本特征 封装 封装demo 继承 继承demo 多态 面向对象的三大基本特征 我们说面向对象的开发范式&#xff0c;其实是对现实世界的理解和抽象的方法&#xff0c;那么&#xff0c;具体如何将现实世界抽象成代码呢&#xff1f;这就需要运用到面向对象的三大…

从ChatGPT与New Bing看程序员为什么要学习算法?

文章目录为什么要学习数据结构和算法&#xff1f;ChatGPT与NEW Bing 的回答想要通关大厂面试&#xff0c;就不能让数据结构和算法拖了后腿业务开发工程师&#xff0c;你真的愿意做一辈子CRUD boy吗&#xff1f;对编程还有追求&#xff1f;不想被行业淘汰&#xff1f;那就不要只…

2023年网络安全比赛--CMS网站渗透中职组(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 1.使用渗透机对服务器信息收集,并将服务器中网站服务端口号作为flag提交; 2.使用渗透机对服务器信息收集,将网站的名称作为flag提交; 3.使用渗透机对服务器渗透,将可渗透页面的名称作为flag提交; 4.使用渗透机对服务器渗透,…

一个Bug让人类科技倒退几十年?

大家好&#xff0c;我是良许。 前几天在直播的时候&#xff0c;问了直播间的小伙伴有没人知道「千年虫」这种神奇的「生物」的&#xff0c;居然没有一人能够答得上来的。 所以&#xff0c;今天就跟大家科普一下这个人类历史上最大的 Bug 。 1. 全世界的恐慌 一个Bug会让人类…

jQuery《一篇搞定》

今日内容 一、JQuery 零、 复习昨日 1 写出至少15个标签 2 写出至少7个css属性font-size,color,font-familytext-algin,background-color,background-image,background-sizewidth,heighttop,bottom ,left ,rightpositionfloatbordermarginpadding 3 写出input标签的type的不…

flex布局左边宽度固定,右边宽度动态扩展问题

我们希望在一个固定宽度的容器中&#xff0c;分左右两边&#xff0c;左边宽度固定大小&#xff0c;右边占满&#xff0c;使用flex布局时&#xff0c;如下&#xff1a; 对应代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta…

LeetCode - 198 打家劫舍

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装…
最新文章