计算机是如何计算四则运算表达式的?

news2024/10/5 21:16:08

🎉welcome🎉
✒️博主介绍:博主大一智能制造在读,热爱C/C++,会不定期更新系统、语法、算法、硬件的相关博客,浅浅期待下一次更新吧!
✈️算法专栏:算法与数据结构
😘博客制作不易,👍点赞+⭐收藏+➕关注

文章目录

  • 引言
  • 中缀表达式
  • 后缀表达式
  • 中缀转后缀
  • 总结

引言

四则运算在我们的生活中无处不在,当出去买东西的时候,结账时收银员拿着计算器对我们买的东西进行计算的时候就进行了四则运算,在我们还是小学的时候,数学作业当中也充斥着大量的四则运算,这些表达式对于我们往往是可以很快得出结果的,因为我们清楚的知道表达式当中运算符的优先级,如括号内部优先计算,乘除优先计算,可是计算机如何得知这些?它知道这些字符的优先级吗?如果不知道它是如何去计算的呢?

中缀表达式

我们平时用的标准的四则运算表达式就是中缀表达式,如:3×(4+7)+2÷10,这种表达式对于我们而言是很轻松就能看懂的,那计算机可以吗?从计算机的角度来看或许并不可以,计算机如何去识别优先级?或者说我们写的程序如何去计算?如果没有括号的出现是可以实现的,但是很麻烦,或者说我们的水平无法实现,那计算机如何进行四则计算?通过观察可以发现,括号是成双成对的出现的,则有左括号一定就会出现右括号,那利用栈就可以将括号问题解决,同时利用栈也可以计算出最终结果,但是这时是需要两个栈的,那有没有办法只用一个栈解决呢?这里就可以使用后缀表达式来解决。

后缀表达式

后缀表达式,又称逆波兰表达式,是由波兰逻辑学家Jan Lukasiewicz发明的,它是一种不需要括号的表达式,如:3 4 7 + * 2 10 / +就是上面中缀表达式例子的的后缀表达式,这时的后缀表达式就可以直接用一个栈来处理,如3 4 7 + * 2 10 / +,它用栈进行计算的过程如下:

  1. 3 4 7 入栈,因为前三个数字是没有符号的,这时栈顶元素是7,下一个元素是4。

  2. 接下来遇到第一个符号+,这时候取出栈最上面的两个元素7和4,进行相加操作,得到11,然后入栈,这时栈内元素有3 11。

  3. 接下来接着遇到符号*,在计算机中*表示相乘,这时取出栈最上面的两个元素11和3进行相乘,得到33,将33入栈,栈内元素变成33。

  4. 接下来是两个数2和10,将它们两个入栈。

  5. 接着是/,在计算机中/表示相除,取出栈最上面两个元素10和2,相除得5,再将5入栈,下一个是符号+,将栈内最上面两个元素取出,相加得38,这个时候表达式结束,结果为38。

int posnota(string str)
{
	stack<int> sum;
	while (!str.empty())
	{
		if (str[0] == ' ') str.erase(0, 1);//当有空格的时候对空格进行删除操作
		if(str[0] <= '9' && str[0] >= '0')//遇到这个区间的数一定是数字
		{
			string tmp;
			while (str[0] != ' ')//遇到下一个空格的时候证明该数结束
			{
				tmp += str[0];
				str.erase(0, 1);
			}
			sum.push(stoi(tmp));
		}
		if (str[0] == '+')
		{
			str.erase(0, 1);
			int x = sum.top();
			sum.pop();
			int y = sum.top();
			sum.pop();
			int z = x + y;
			sum.push(z);
		}
		if (str[0] == '-')
		{
			str.erase(0, 1);
			int x = sum.top();
			sum.pop();
			int y = sum.top();
			sum.pop();
			int z = x - y;
			sum.push(z);
		}
		if (str[0] == '*')
		{
			str.erase(0, 1);
			int x = sum.top();
			sum.pop();
			int y = sum.top();
			sum.pop();
			int z = x * y;
			sum.push(z);
		}
		if (str[0] == '/')
		{
			str.erase(0, 1);
			int x = sum.top();
			sum.pop();
			int y = sum.top();
			sum.pop();
			int z = x / y;
			sum.push(z);
		}
	}
	return sum.top();
}

在这里插入图片描述

运行结果是正常的,但是我们在日常生活中见到的都是中缀表达式,我们如何去得知后缀表达式?

中缀转后缀

中缀表达式是可以转成后缀表达式的,如何去转换呢?拿例子3*(4+7)+2/10来进行解释:

  1. 开始是数字3,直接将其输出,接下来遇到了*号,这时候栈内没有任何元素,将*号入栈。
  2. 接下来遇到了(,左括号的优先级比*号高,则入栈,并且有(,一定会出现匹配的右括号,当遇到右括号的时候,可以将左括号上面的元素全都出去。
  3. 接下来是数字4,直接输出,然后遇到了+号,还没有遇到),将+号入栈,栈内元素现在为+ ( *,接下来是数字7,输出。
  4. 遇到了),开始出栈,先是+,接着是(,匹配成一对括号,结束出栈。
  5. 遇到+,+优先级比栈顶元素*号低,这个时候将栈内元素(没有符号不高于+的优先级)全部出栈,在将+入栈。
  6. 遇到数字2,输出,接着是/号,优先级高于栈顶元素+,入栈。
  7. 遇到数字10,输出,表达式结束,将栈内全部元素输出。
int p[4] = {0, 0, 1, 1};
string o = "+-*/";
bool tf;

string infix_to_pos(string& str)
{
	stack<char> sym;
	string tmp;
	tmp.erase(0, 1);
	while (!str.empty())
	{
		while (str[0] >= '0' && str[0] <= '9')
		{
			tmp += str[0];
			str.erase(0, 1);
		}
		tmp += ' ';
		if (str[0] == ')')
		{
			while (!(sym.top() == '('))//遇到右括号则栈内一定会出现左括号
			{
				tmp += sym.top();
				sym.pop();
				tmp += ' ';
			}
			sym.pop();
			str.erase(0, 1);
		}
		//当当前一定是符号的时候,只要栈为空,或者当前符号优先级高于栈顶元素,则就将符号入栈,或者当栈顶元素为(时候直接入栈
		if ((str[0] <= '0' || str[0] >= '9') && (sym.empty() ||tf|| p[o.find(str[0])] > p[o.find(sym.top())]))
		{
			tf = false;
			sym.push(str[0]);
			str.erase(0, 1);
		}
		//当遇到左括号的时候入栈,并且打上记号为true,使其他符号不与(比优先级,直接进去入栈
		if (str[0] == '(')
		{
			sym.push(str[0]);
			str.erase(0, 1);
			tf = true;
		}
		//当前符号的优先级是不高于栈顶元素的,就出栈顶元素,并且栈不能为空
		while ((str[0] <= '0' || str[0] >= '9') && !sym.empty() && p[o.find(str[0])] <= p[o.find(sym.top())])
		{
			tmp += sym.top();
			sym.pop();
			tmp += ' ';
		}
	}
	return tmp;
}

在这里插入图片描述

通过中缀转后缀,在让程序利用后缀去计算得出的答案是正确的,表明当前程序无问题。

总结

对于计算机而言,日常生活中的中缀表达式是比较难以理解的,而逆波兰表达式可以很好的去解决这一问题,同时中缀表达式可以转变成逆波兰表达式。

🚀专栏:算法与数据结构
🙉都看到这里了,留下你们的👍点赞+⭐收藏+📋评论吧🙉

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python爬虫实战(基础篇)—4获取古诗词给孩子学习(附完整代码)

今天我们来获取古诗词网站的一些古诗词来提供给孩子们学习 PS前面几节课的内容在专栏这里&#xff0c;欢迎大家考古&#xff1a;点我 首先我们看一下网站&#xff1a;点我&#xff0c;今天我们来获取一下【唐诗三百首】 第 1 步&#xff1a;网页分析 在网页中我们发现有许多以…

KnowStreaming系列教程第三篇——调度任务模块

前一篇文章KnowStreaming系列教程第二篇——项目整体架构分析_诸葛子房_的博客-CSDN博客 讲述了KS的整体项目目录&#xff0c;这边文章来讲述下KS在调度模块里面对于指标采集和元数据同步 一、调度模块代码主要在km-task里面 public class TaskClusterAddedListener impleme…

Docker-compose简介和部署编排 and Docker 私有仓库Harbor的简介和部署

Docker-compose简介和部署编排 and Docker 私有仓库的简介和部署 一、Docker-compose简介Ⅰ、compose概述Ⅱ、YAML 文件格式及编写注意事项Ⅲ、YAML支持的数据结构 二、compose部署安装Ⅰ、Docker Compose 环境安装Ⅱ、Docker Compose配置常用字段Ⅲ、Docker Compose 常用命令 …

【工具】js字符串扩展格式化方法format 格式化文本

有序的格式化文本&#xff0c;使用{number}做为占位符 通常使用&#xff1a;format("this is {0} for {1}", "a", "b") 》 this is a for b 形参: pattern – 文本格式 arguments – 参数 返回值: 格式化后的文本 /*** 设置字符串format函数* …

汽车分析,随时间变化的燃油效率

简述 今天我们来分析一个汽车数据。 数据集由以下列组成&#xff1a; 名称&#xff1a;每辆汽车的唯一标识符。MPG&#xff1a;燃油效率&#xff0c;以英里/加仑为单位。气缸数&#xff1a;发动机中的气缸数。排量&#xff1a;发动机排量&#xff0c;表示其大小或容量。马力&…

torchsort安装报错:ModuleNotFoundError: No module named ‘torch‘

【问题】 安装torchsort时报错ModuleNotFoundError: No module named torch。 但实际已安装torch。 【解决】 是pip版本的问题&#xff0c;回退至旧版即可。 pip --version # 查看当前pip版本 pip install pip # 查看pip所有版本 pip install pip23.0 # 回退pip至较新版本&…

Vue3 Element-plus分页效果动态数据展示

Vue3 Element-plus实现分页动态数据展示 环境&#xff1a;vue3tsviteelement plus 接着前面的axios封装请求数据&#xff0c;继续 直接贴代码 <template><div class"news"><ul><li v-for"item in state.list">{{item.title}}&l…

蓝牙协议之蓝牙车载BLE-GATT基础知识

蓝牙协议之蓝牙车载BLE-GATT基础知识 一&#xff1a;定义 GATT 的全名是 Generic Atribute Profile &#xff0c;它定义两 BLE 设备通过叫做 Service 和 Characteristic 的东西进行通信。GATT 就是使用了ATT (Atribute Protoo)协议&#xff0c;ATT 协议把 Service,Characterist…

RN输入框默认设置数字键盘

<TextInput keyboardType"numeric"/> keyboardType 决定弹出何种软键盘类型&#xff0c;譬如numeric&#xff08;纯数字键盘&#xff09;。 See screenshots of all the types here. 这些值在所有平台都可用&#xff1a; defaultnumber-paddecimal-padnume…

【电商小知识】7个步骤让你快速了解跨境电商!

近几年来&#xff0c;随着互联网的发展&#xff0c;国内外的商业贸易越来越流畅&#xff0c;直播电商的火爆也带动着一大批相关的产业链发展&#xff0c;其中跨境电商就是尤为突出的一个。尽管在国内做跨境电商的企业数量非常之多&#xff0c;但仍有许多新人争相入局&#xff0…

无涯教程-jQuery - Ajax Tutorial函数

AJAX是用于创建交互式Web应用程序的Web开发技术。如果您了解JavaScript,HTML,CSS和XML,则只需花费一个小时即可开始使用AJAX。 为什么要学习Ajax? AJAX代表 A 同步 Ja vaScript和 X ML。 AJAX是一项新技术,可借助XML,HTML,CSS和Java Script创建更好,更快,更具交互性的Web应用…

【Java】JUC并发编程-进程线程

目录 一、什么是JUC二、进程和线程1、进程2、线程 三、线程的六种状态四、wait与sleep的区别五、并发与并行1、串行模式2、并行模式3、并发模式4、管程 六、用户线程与守护线程1、用户线程&#xff08;自定义线程&#xff09;2、守护线程&#xff08;比如垃圾回收&#xff09; …

怎么来说?学习HashSet类

与这道题相关 》 345. 反转字符串中的元音字母 目录 一、HashSet是什么&#xff1f; 二、使用步骤 总结 一、HashSet是什么&#xff1f; HashSet是基于HashMap来实现的&#xff0c;实现了Set接口&#xff0c;同时还实现了序列化和可克隆化。而集合&#xff08;Set&#xff…

为什么程序员不喜欢写注释?

现在的项目开发里&#xff0c;代码注释就像程序员的头发&#xff0c;越来越少。 尤其是国内&#xff0c;这种现象不仅是在小公司小团队中司空见惯&#xff0c;就算在大公司&#xff0c;以及大团队中的开源项目里&#xff0c;也是屡见不鲜。 上图是我在阿里的 Druid 项目源码里…

SQL-每日一题【626.换座位】

题目 表: Seat 编写SQL查询来交换每两个连续的学生的座位号。如果学生的数量是奇数&#xff0c;则最后一个学生的id不交换。 按 id 升序 返回结果表。 查询结果格式如下所示。 示例 1: 解题思路 前置知识 MySQL 的 MOD() 函数是取模运算的函数&#xff0c;它返回两个数相除…

el-popover 的content内容换行

需求&#xff1a;把el-popover的content内容进行换行 <el-popoverplacement"bottom"width"450"trigger"click"><div class"custom-content">示例&#xff1a;如果您在 2 个托盘上运输 40 箱纸&#xff08;每个托盘上20 箱…

基于SpringBoot+Vue的“智慧食堂”系统设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

三、Web安全相关知识

请勿用于非法用途 文章目录 一、Web源码框架二、目录结构1、静态资源2、WEB-INF&#xff08;1&#xff09;classes&#xff08;2&#xff09;lib&#xff08;3&#xff09;web.xml 二、web脚本语言1、脚本种类&#xff08;1&#xff09;ASP&#xff08;2&#xff09;ASP.NET&am…

Vue的下载以及MVVM分析

&#x1f600;前言本片文章是vue系列第一篇整理了vue的基础和发展史 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f609;&#x1f6…

服务器——Nginx安装及静态配置、部署

目录 Nginx 安装Nginx步骤 安装yum-utils 配置nginx.repo源 安装nginx 系统启动nginx服务器 nginx.conf配置 关闭nginx服务器 配置文件启动nginx服务 配置文件编写 启动nginx服务 关闭nginx服务 服务器——Nginx安装及静态配置、部署。 直接在云服务器中启动项目&…