栈知识点训练之计算(calc)

2024-01-25 22:20
文章标签 知识点 训练 计算 calc

本文主要是介绍栈知识点训练之计算(calc),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、问题描述

【题目描述】

        小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*”,“/”,“^”,求出的值就是密码。小明数学学得不好,还需你帮他的忙。(“/”用整数除法)

【输入】

        共1行,为一个算式。

【输出】

        共1行,就是密码。

二、知识点考察

本题考察的是数据结构之栈的运用。可以使用C++ STL 内置的stack来解决此问题,使用stack需要引入对应的头文件#include<stack>

三、解题思路 

        针对该题目,我们需要使用到两个栈,一个栈用来存储数值,不妨命名为values,另一个栈用来存储操作符,不妨命名为operators,针对不同的数据内容[数字或者运算符],需要做不同的处理。

        在这里,为了大家更方便理解,对输入输出样例进行一个模拟

(1)准备两个栈,一个values,一个operators,针对样例数据,如下所示:

(2)计算规则如下

 (3)计算过程模拟

有计算表达式如右:1+(3+2)*(7^2+6*9)/(2),现按照以上计算规则进行计算过程模拟

① 从左往右遍历字符串,遇到数字1,将其放入values栈

② 遇到运算符+,因为当前operators栈为空,因此直接将其放入operators栈

③ 遇到运算符(,根据规则,直接将运算符(其放入operators栈中 

④ 遇到数字3,根据规则,将数字入栈到values中

⑤ 遇到运算符+,根据规则,由于当前operators不为空,因此需要比较+和operators栈顶运算符的优先级,发现+的优先级高于(,因此将+入栈

⑥ 遇到数字2,根据规则,将数字入栈到values中 

⑦ 遇到运算符),根据规则,需要计算两个括号之间表达式的值,将结果放入values栈中,每次计算需要把values上面的两个数出栈同时operators的一个运算符出栈

由于当前operators的栈顶已经是(了,因此计算结束,同时需要将栈顶的(出栈

⑧ 继续遍历字符串,遇到运算符*,由于operators栈不为空,因此需要比较operators栈顶运算符+和当前运算符*的优先级关系,发现*的优先级高于+,所以将运算符*入栈

⑨ 遇到运算符(,根据规则,直接将运算符(其放入operators栈中  

⑩ 遇到数字7,根据规则,将数字入栈到values中 

⑪ 继续遍历字符串,遇到运算符^,由于operators栈不为空,因此需要比较operators栈顶运算符(和当前运算符^的优先级关系,发现^的优先级高于(,所以将运算符^入栈 

⑫ 遇到数字2,根据规则,将数字入栈到values中 

⑬ 继续遍历字符串,遇到运算符+,由于operators栈不为空,因此需要比较operators栈顶运算符^和当前运算符+的优先级关系,发现^的优先级高于+,因此需要先对^进行计算,也就是计算7^2=49,将7、2、^出栈,49放入values栈中

 +的优先级大于(,因此将刚刚的+放入operators栈中

⑭ 遇到数字6,根据规则,将数字入栈到values中  

⑮ 继续遍历字符串,遇到运算符*,由于operators栈不为空,因此需要比较operators栈顶运算符+和当前运算符*的优先级关系,发现栈顶运算符+的优先级小于* ,因此*直接入栈

⑯ 遇到数字9,根据规则,将数字入栈到values中   

⑰ 遇到运算符),根据规则,需要计算两个括号之间表达式的值,将结果放入values栈中,将9、6出栈,*出栈,计算结果54放入values栈中

由于operators的栈顶运算符还不是(,因此继续计算 :54、49、+出栈,计算结果54+49=103入栈,由于当前operators栈顶已经是(了,计算结束,同时将(出栈

⑱ 继续遍历字符串,遇到运算符/,由于operators栈不为空,因此需要比较operators栈顶运算符*和当前运算符/的优先级关系,发现当前运算符/的优先级不高于*号 ,因此先进行计算:103、5、*出栈,计算103*5=515,515放入values栈中

由于/的优先级高于栈顶的+,因此将/入栈,如下:

⑲ 遇到运算符(,根据规则,将其直接放入operators栈中,遇到数字2,将其直接放入values栈中

⑳ 遇到运算符),由于现在栈顶元素是(,直接将其弹出即可

        此时字符串已经遍历完毕,需要对栈内的数据进行运算,将515、2、/ 出栈,计算515/2=257,将257入栈,接着计算257、1、+出栈,计算257+1=258,将其入栈,由于operators栈已经空了,所以结果就是values栈顶的值258。

四、代码实现

        学习了解题思路之后,我们就可以按照该思路来编写代码,我们主要代码思路分为三大部分,如下:

1、主程序

2、priority函数(主要用于返回操作符的优先级)

3、calculate函数(主要用于进行栈内数据的计算)

对于第一部分主程序而言,又可以进一步分为三个步骤:

1、读入字符串

2、根据规则进行对应的出入栈操作

3、输出结果

对于第二部分priority而言,可以进一步分为四个步骤:

1、如果操作符是+或者-,返回1

2、如果操作符是*或者/,返回2

3、如果操作符是^,返回3

4、其它返回0

对于第三部分calculate而言,可以进一步分为三个步骤:

1、从values栈中获取两个操作数

2、从operators栈中获取操作符

3、计算值,并将结果放入values栈

具体代码如下:

1、定义一个带有main函数的基本程序框架

2、定义priority函数(返回优先级)、calculate函数(计算数据) 

3、保存数值的栈values、保存运算符的栈operators

4、定义代码中需要用到的相关变量

5、读入字符串、计算长度 

 

 6、遍历字符串,对运算符和数字进行操作,对于一个表达式而言,如果在处理的过程中遇到的一直是数字,那么则计算这些数字组成的数值

 

7、 如果遇到运算符,需要先把之前计算的数字放入values栈中,然后判断当前遇到的是何种运算符,如果是(,则直接将其放入operators栈,如果是),则计算()两边的表达式,且计算完毕后将(出栈。

8、如果operators栈为空,那么直接将运算符入栈,否则比较当前运算符和栈顶运算符的优先级,如果栈顶的优先级大于等于当前运算符的优先级,则调用calculate函数计算,否则将当前运算符直接入栈。

9、当字符串遍历完毕之后,如果最后一项是数字,则将其入栈,然后不断取出operators栈中的运算符进行运算,直到为空,最终values栈中只有一个数值,就是最终答案,取出输出即可。 

接下来看一看priority函数calculate函数的函数体内容:

 

 

五、完整参考代码

 

#include<bits/stdc++.h>
using namespace std;//保存数值 
stack<int> values;
//保存运算符 
stack<char> operators;//返回运算符优先级 
int priority(char c) {int ret = 0;switch(c) {case '+':case '-':ret = 1;break;case '*':case '/':ret = 2;break;case '^':ret = 3;break;}return ret;
}//计算数据结果 
void calculate() {int x = 0, y =0, result = 0;char op;y = values.top();values.pop();x = values.top();values.pop();op = operators.top();operators.pop();switch(op) {case '+':result = x+y;break;case '-':result = x-y;break;case '*':result = x*y;break;case '/':result = x/y;break;case '^':result = pow(x,y);break;}values.push(result);
}//定义一个带有main函数的基本程序框架
int main() {int value = 0;  //计算字符串当中的数值int len = 0;    //用于记录字符串长度int has_num = 0; //用来标记是否识别到数值char ch; //当前字符string chs; //当前字符串 cin >> chs;len = chs.length(); //遍历字符串for(int i=0;i<len;i++) {ch = chs[i];//如果遇到的一直是数字,则计算这些数字组成的数值if(isdigit(ch)) {value = value*10 + ch-'0';has_num = 1;}//不是数字,则是操作符 else {if(has_num) {values.push(value);value = 0;has_num = 0;}// ( 直接入栈 if(ch=='(') {operators.push(ch);continue;}if(ch==')') {while(operators.top()!='(') {calculate();}operators.pop();continue;} if(operators.empty()) {operators.push(ch);} else {while(!operators.empty()&&priority(operators.top())>=priority(ch)) {calculate();}operators.push(ch);}}} if(has_num) {values.push(value);}while(!operators.empty()) {calculate();}cout << values.top() << endl;return 0;
}

六、总结 

         学习算法的路,每一步都算数。多多练题、多多思考,理解算法思维和数据结构背后的本质才是最重要的,更多更有趣的算法知识请关注我:小C哈哈哈😀。

这篇关于栈知识点训练之计算(calc)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/644795

相关文章

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

XTU 1237 计算几何

题面: Magic Triangle Problem Description: Huangriq is a respectful acmer in ACM team of XTU because he brought the best place in regional contest in history of XTU. Huangriq works in a big compa

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚:

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering)

Spark MLlib模型训练—聚类算法 PIC(Power Iteration Clustering) Power Iteration Clustering (PIC) 是一种基于图的聚类算法,用于在大规模数据集上进行高效的社区检测。PIC 算法的核心思想是通过迭代图的幂运算来发现数据中的潜在簇。该算法适用于处理大规模图数据,特别是在社交网络分析、推荐系统和生物信息学等领域具有广泛应用。Spa

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验