本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的。同时也希望文章能够让你有所收获,与君共勉!

表达式求值

给定一个表达式,其中运算符仅包含+,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

注意:

数据保证给定的表达式合法。

题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-1+2,(2+2)*(-(1+1)+2) 之类表达式均不会出现。

题目保证表达式中所有数字均为正整数。

题目保证表达式在中间计算过程以及结果中,均不超过 231−1。

题目中的整除是指向 0 取整,也就是说对于大于 0 的结果向下取整,例如 5/3=1,对于小于 0 的结果向上取整,例如 5/(1−4)=−1

C++和Java中的整除默认是向零取整;Python中的整除//默认向下取整,因此Python的eval()函数中的整除也是向下取整,在本题中不能直接使用。

输入格式

共一行,为给定表达式。

输出格式

共一行,为表达式的结果。

数据范围

表达式的长度不超过 105。

输入样例:

(2+2)*(1+1)

输出样例:

8

算法原理

①从表达式中分离出一个个数字整体(所以while循环对于“123”这样的整个数作为整体处理。)

②遇到符号,要按照符号的优先级运算。

这里的op是优先级单调递增栈。

  • 如果当前运算优先级比栈顶高,就直接压栈。
  • 如果当前的与之前相等或更低,且符号栈的顶部符号不是左括号(,且符号栈存在符号,则先进行取栈顶符号运算,再将当前符号加入到符号栈中-。如:2+3*4+5,符号栈先进+,*号比+的优先级要大,所以直接进栈,后面的加号比*的优先级要小,所以要先进行乘法运算

③括号是特殊处理的,如果没有遇到右括号,则运算最多只能处理到上一个左括号,例如2*(3+4),在加号位置不能先算2*3,而是先等待,因为符号栈顶部是(,再括号里面如果存在像2*(2+3*4+5),按照规则2也会先把3*4算出来并放进数字栈中,直到遇到)就从右到左取出数字栈中的数字(符号栈顶的符号)进行运算直至左括号(。

代码实现

#include <iostream>
#include <string>
#include <algorithm>
#include <stack>
#include<unordered_map> using namespace std; stack<int> num;
stack<char> op; void eval(){
int b = num.top(); num.pop();
int a = num.top(); num.pop();
char c =op.top() ;op.pop();
int x ;
if(c == '+') x = a+b;
else if(c == '-') x= a-b;
else if(c == '*') x= a*b;
else x = a/b;
num.push(x);
} int main(void){
unordered_map<char,int> pr{{'+',1},{'-',1},{'*',2},{'/',2}}; // 定义恏优先级
string str; cin >> str; for(int i=0; i < str.size() ; i++){
auto c = str[i];
if(isdigit(c)){
int x = 0, j=i;
while(j<str.size() && isdigit(str[j])){ // 将字符串转化成数字
x = x * 10 + str[j++] - '0';
// j++;
}
i = j-1;
num.push(x);
}
else if (c == '('){ // 左括号直接进符号栈
op.push(c);
}
else if (c == ')'){ // 右括号:从右到左进行运算,知道遇到左括号停下,并且弹出左括号
while(op.top() != '(') eval();
op.pop();
}
else{ // 遇到普通操作符
// 符号栈不为空,栈顶符号不为"(",当前符号的优先级比栈顶的要小(-,+),说明栈顶符号为*/,
while(op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
op.push(c); // 要先进行乘除运算后再将+,-存入符号栈中。
}
} while(op.size()) eval(); // 最后对+,-运算进行操作
cout << num.top() << endl; // 最后的num一定是运算结果。
return 0;
}

2022-11-10 Acwing每日一题的更多相关文章

  1. [ 9.10 ]CF每日一题系列—— 186A模拟处理字符串

    Description: 跟你两个不相同的字符串,问你能否将第一个字符串任意两个字母交换一次使得两字符串相同,YES or NO Solution: 一维模拟就好了 #include <iost ...

  2. CISP/CISA 每日一题 11

    CISA 每日一题(答) 一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓 ...

  3. CISP/CISA 每日一题 10

    CISA 每日一题(答)一个合理建造的数据仓库应当支持下列三种基本的查询格式: 1.向上溯源和向下溯源——向上溯源是对数据进行总计:向下溯源是将数据进行细化: 2.交叉溯源——通过通用属性访问数据仓库 ...

  4. 老男孩IT教育-每日一题汇总

    老男孩IT教育-每日一题汇总 第几天 第几周 日期 快速访问链接 第123天 第二十五周 2017年8月25日 出现Swap file….already exists以下错误如何解决? 第122天 2 ...

  5. CISP/CISA 每日一题 五

    CISA 每日一题(答) 信息系统审计师要确认系统变更程序中的: 1.变更需求应有授权.优先排序及跟踪机制: 2.日常工作手册中,明确指出紧急变更程序: 3.变更控制程序应同时为用户及项目开发组认可: ...

  6. [每日一题]ES6中为什么要使用Symbol?

    关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...

  7. [每日一题]面试官问:谈谈你对ES6的proxy的理解?

    [每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...

  8. 【JavaScript】【dp】Leetcode每日一题-解码方法

    [JavaScript]Leetcode每日一题-解码方法 [题目描述] 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : 'A' -> 1 'B' -> 2 ... 'Z' -& ...

  9. 【python】Leetcode每日一题-森林中的兔子

    [python]Leetcode每日一题-森林中的兔子 [题目描述] 森林中,每个兔子都有颜色.其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色.我们将这些回答放在 answers ...

  10. 【python】Leetcode每日一题-笨阶乘

    [python]Leetcode每日一题-笨阶乘 [题目描述] 通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积.例如,factorial(10) = 10 * 9 * 8 * 7 * 6 ...

随机推荐

  1. 第三十五篇:vue3,(组合式api的初步理解)

    好家伙, 来一波核心概念:数据劫持是响应式的核心 1.由set up开始 (1)vue3中的一个新的配置项,值为一个函数. (2)组件中所用的到的:数据,方法,计算属性均要配置在set up中. (3 ...

  2. Linux虚拟机启动报错挂载点丢失

    fstab 挂载失败 实验准备 1) 准备:vim /etc/fstab /mnt1/cdrom 挂载点不在 2) 系统启动报错截图 修复步骤 /etc/fstab 中的错误和损坏的文件系统可能会阻止 ...

  3. 华为云计算灾备产品BCManager 及eBackup的组网方式

    BCManager的作用 OceanStor BCManager是面向企业数据中心存储容灾业务的管理软件,实现容灾.双活.两地三中心等容灾环境的管理,具备多种数据库应用与虚拟化环境的容灾管理功能,简单 ...

  4. KDB_Database_Link 使用介绍

    kdb_database_link 是 KingbaseES 为了兼容oracle 语法而开发的跨数据库访问扩展,可用于访问KingbaseES, Postgresql , Oracle .以下分别介 ...

  5. KingbaseES R6 集群repmgr.conf参数'recovery'测试案例(一)

    KingbaseES R6集群repmgr.conf参数'recovery'测试案例(一) 案例说明: 在KingbaseES R6集群中,主库节点出现宕机(如重启或关机),会产生主备切换,但是当主库 ...

  6. Pytorch: repeat, repeat_interleave, tile的用法

    https://zhuanlan.zhihu.com/p/474153365 torch.repeat 使张量沿着某个维度进行复制, 并且不仅可以复制张量,也可以拓展张量的维度: import tor ...

  7. Ubuntu22.04 安装配置流水账

    前两天为了测一个CH340的bug, 装了三遍20.04. bug解决完, 心想反正也要重新装各种软件, 不如直接装22.04吧. 把涉及的安装记录一下方便将来参考. 制作启动U盘 在Ubuntu网站 ...

  8. Linux病毒扫描工具ClamAV(Clam AntiVirus)安装使用

    在线检测木马病毒的网址:https://www.virustotal.com/gui/home/upload 一.简介 ClamAV(Clam AntiVirus)是Linux平台上的开源病毒扫描程序 ...

  9. KVM 下如何关闭 virbr0

    安装KVM 后都会发现网络接口里多了一个叫做 virbr0 的虚拟网络接口: 这是由于安装和启用了 libvirt 服务后生成的,libvirt 在服务器(host)上生成一个 virtual net ...

  10. #css#如何使用hover,实现父对子的样式改变?

    思路及做法: 鼠标移动到父盒子的时候, 里面所有的子盒子的样式都发生变化的, 只需要直接在hover后面加上空格, 并且加上子盒子的类名 ,里面再写其他样式 .父盒子的类名:hover .子盒子的类名 ...