栈知识点训练之计算(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

相关文章

嵌入式软件工程师应聘知识点

嵌入式软件工程师应聘 修改浏览权限 | 删除 数据结构(C语言)部分常考的知识点: 1、局部变量能、全局变量和静态变量 2、堆和栈 3、Const、volatile、define、typedef的用途 4、链表(比如链表的插入、删除和排序) 5、排序(考查冒泡法的较多) 6、可重入函数 、malloc函数 7、指针(常考函数指针,函数指针,数组指针,指针数组和

计算绕原点旋转某角度后的点的坐标

问题: A点(x, y)按顺时针旋转 theta 角度后点的坐标为A1点(x1,y1)  ,求x1 y1坐标用(x,y)和 theta 来表示 方法一: 设 OA 向量和x轴的角度为 alpha , 那么顺时针转过 theta后 ,OA1 向量和x轴的角度为 (alpha - theta) 。 使用圆的参数方程来表示点坐标。A的坐标可以表示为: \[\left\{ {\begin{ar

数据库期末复习知识点

A卷 1. 选择题(30') 2. 判断范式(10') 判断到第三范式 3. 程序填空(20') 4. 分析填空(15') 5. 写SQL(25') 5'一题 恶性 B卷 1. 单选(30') 2. 填空 (20') 3. 程序填空(20') 4. 写SQL(30') 知识点 第一章 数据库管理系统(DBMS)  主要功能 数据定义功能 (DDL, 数据定义语

YOLO v3 训练速度慢的问题

一天一夜出了两个模型,仅仅迭代了200次   原因:编译之前没有将Makefile 文件里的GPU设置为1,编译的是CPU版本,必须训练慢   解决方案: make clean  vim Makefile make   再次训练 速度快了,5分钟迭代了500次

【云计算 复习】第1节 云计算概述和 GFS + chunk

一、云计算概述 1.云计算的商业模式 (1)软件即服务(SaaS) 有些景区给游客提供烧烤场地,游客需要自己挖坑或者砌烧烤台,然后买肉、串串、烧烤。 (2)平台即服务(PaaS) 有些景区给游客提供烧烤场地,同时搭建好烧烤台,游客只需要自己带食材和调料、串串、烧烤。 (3)基础设施即服务(IaaS) 有些景区给游客提供烧烤场地,同时搭建好烧烤台,还有专门的厨师来烧烤,用户不需要关心前面的所有

将一维机械振动信号构造为训练集和测试集(Python)

从如下链接中下载轴承数据集。 https://www.sciencedirect.com/science/article/pii/S2352340918314124 import numpy as npimport scipy.io as sioimport matplotlib.pyplot as pltimport statistics as statsimport pandas

6月21日训练 (东北林业大学)(个人题解)

前言:   这次训练是大一大二一起参加的训练,总体来说难度是有的,我和队友在比赛时间内就写出了四道题,之后陆陆续续又补了了三道题,还有一道题看了学长题解后感觉有点超出我的能力范围了,就留给以后的自己吧。话不多说,上正文。 正文:   Problem:A 幸运数字: #include <bits/stdc++.h>using namespace std;int sum,ans;in

什么是dB?dBm、dBc、dBi、dBd怎么计算,有什么区别?

什么是dB?dBm、dBc、dBi、dBd怎么计算,有什么区别? 引言 在电子工程、通信和音频领域,dB(分贝)是一个常见的术语。许多人刚接触时可能会感到困惑,因为它不仅仅是一个简单的单位,还有多种不同的形式,如dBm、dBc、dBi和dBd。这篇文章将详细解释这些概念,并介绍如何计算它们,帮助初学者更好地理解和应用。 什么是dB? dB,即分贝,是一种表示两个数值比值的对数单位。分贝的基

国产AI算力训练大模型技术实践

&nbsp;&nbsp; ChatGPT引领AI大模型热潮,国内外模型如雨后春笋,掀起新一轮科技浪潮。然而,国内大模型研发推广亦面临不小挑战。面对机遇与挑战,我们需保持清醒,持续推进技术创新与应用落地。 为应对挑战,我们需从战略高度全面规划大模型的研发与运营,利用我们的制度优势,集中资源攻坚克难。通过加强顶层设计,统一规划,并加大政策与资源的扶持,我们必将推动中国人工智能实现从追赶者到

408计算机网络知识点——第四章 网络层

文章目录 网络层概述分组转发和路由选择分组转发路由选择 网络层向上层提供的两种服务面向连接的虚电路服务无连接的数据报服务 网际协议IP网际协议IP异构网络互连IPv4地址及其编址方法IPv4地址概述IPv4地址的表示方法分类编址A类地址B类地址C类地址特殊地址 划分子网子网掩码默认子网掩码 无分类编址地址掩码CIDR地址块路由聚合 IPv4地址的应用规划采用定长的子网掩码进行子网划分采用