当前位置:网站首页>逆波兰表达式求值<难度系数>
逆波兰表达式求值<难度系数>
2022-06-28 07:23:00 【华为云】
题述:根据 逆波兰表示法,求表达式的值。有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。注意 两个整数之间的除法只保留整数部分。可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例1:
输入:tokens = [“2”,“1”,"+",“3”,"*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例2:
输入:tokens = [“4”,“13”,“5”,"/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例3:
输入:tokens = [“10”,“6”,“9”,“3”,"+","-11","","/","",“17”,"+",“5”,"+"]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
提示:
- 1 <= tokens.length <= 10^4^
- tokens[i] 是一个算符("+"、"-"、"*" 或 “/”),或是在范围 [-200, 200] 内的一个整数
逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
中缀表达式面临的最大问题在于程序不方便运算,因为运算符优先级的问题,所以我们处理这种问题可以先将中缀表达式转换成后缀表达式,然后用后缀表达式进行运算。
大概了解下中缀表达式转后缀表达式,这里需要借助栈
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:
- 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
- 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中
🧷 平台:Visual studio 2017 && windows
核心思想:在了解完后缀表达式怎么由中缀表达式转换后,这里题目本意是需要我们计算后缀表达式的值。
🧿 版本一
class Solution {public: int evalRPN(vector<string>& tokens) { stack<int> st; for(const auto str : tokens) { //建议不要这样写,因为如果操作数是负数,就会出bug /*switch(str[0]) { case: '+': //... ... }*/ int left, right; //+、-、*、/,就出两个栈顶的元素,top1对应right,top2对应left,再把计算的结果入栈 if(str == "+") { right = st.top(); st.pop(); left = st.top(); st.pop(); st.push(left + right); } else if(str == "-") { right = st.top(); st.pop(); left = st.top(); st.pop(); st.push(left - right); } else if(str == "*") { right = st.top(); st.pop(); left = st.top(); st.pop(); st.push(left * right); } else if(str == "/") { right = st.top(); st.pop(); left = st.top(); st.pop(); st.push(left / right); } else//操作数 { //入栈前,将字符串转整型 st.push(stoi(str)); } } //返回此时栈顶的元素 return st.top(); }};🧿 版本二 (优化版本一)
优化的点在于 “ 在判断操作符时有大量冗余的代码 ”。
解决方案:
- 封装一个成员函数 (能解决,但还能更好的方法 ?)。
- 这道题使用 map 非常简单,但目前我们还没学,就不谈了。
- 使用逻辑或 “ || ”,这种写法的问题是把运算结果 push 时不知道是什么操作符。解决方法就是定义一个 48 大小的数组建立映射关系,比如在下标 47 的位置存储 “ / ”,然后根据对应的字符就可以取到对应的符号,但是数组里所存储的字符,不是类型,所以没错,~~ 翻车了,连第 2 种方案好像也翻车了,所以这里给成员函数好像是比较好的方案了,或者在 “ || ” 的基础上使用 switch 语句 (这两种方法差不多,只是减少了代码量,本质并没有多少的改进)。无妨,多翻车才能更好的上车嘛 !!!
注:其实也有更好的简化的方案的,只不过目前我们玩不了,这里先吊下大家的胃口 —— C++11 的包装器。也欢迎大家有更好的方案可以在评论区留言。

//版本二(优化版本一)class Solution {public: //解决方案一: void getnum(stack<int>& st, int& l, int& r) {} int evalRPN(vector<string>& tokens) { stack<int> st; for(const auto str : tokens) { int left, right; if(str == "+" || str == "-" || str == "*" || str == "/") { right = st.top(); st.pop(); left = st.top(); st.pop(); switch(str[0]) { case '+': st.push(left + right); break; case '-': st.push(left - right); break; case '*': st.push(left * right); break; case '/': st.push(left / right); break; } } else { st.push(stoi(str)); } } return st.top(); }};🧿 版本三 (优化版本二,骚操作)
这里可以先跳过,把后面 C++11 的包装器、map 等,等学了再来看。
class Solution {public: int evalRPN(vector<string>& tokens) { map<string, function<int(int, int)>> opCountMap = { {"+", [](int x, int y)->int{return x + y;}}, {"-", [](int x, int y)->int{return x - y;}}, {"*", [](int x, int y)->int{return x * y;}}, {"/", [](int x, int y)->int{return x / y;}} }; stack<int> st; for(auto& str : tokens) { if(str == "+" || str == "-" || str == "*" || str == "/") { int right = st.top(); st.pop(); int left = st.top(); st.pop(); st.push(opCountMap[str] (left, right)); } else { st.push(stoi(str)); } } return st.top(); }};边栏推荐
- Self discipline challenge 30 days
- Drawing animated bubble chart with R language
- LeetCode+ 51 - 55 回溯、动态规划专题
- Jinshan cloud team shared | 5000 words to understand how Presto matches with alluxio
- [thanos source code analysis series]thanos query component source code analysis
- hack the box:RouterSpace题解
- LLVM 与 Clang
- File header information cross reference table
- MMR rearrangement (similarity is calculated by editing distance and repeatability)
- Is it safe for flush to open an account online
猜你喜欢

数字藏品市场“三大套路”

es6箭头函数中return的用法

Voice network VQA: make the user's subjective experience of unknown video quality in real-time interaction known

C language tutorial

Kubelet garbage collection (exiting containers and unused images) source code analysis

Compile configuration in file

hack the box:RouterSpace题解

全方位透析真实企业软件测试流程

kubernetes部署thanos ruler的发送重复告警的一个隐秘的坑

C语言教程大全
随机推荐
What is EC blower fan?
自律挑战30天
C language tutorial
炒股开户在手机上安全吗?
华为云计算之物理节点CNA安装教程
Compilation principles final review
7-1 懂的都懂
Mysql8.0和Mysql5.0访问jdbc连接
QT -- communication protocol
Principle and practice of bytecode reference detection
金山云团队分享 | 5000字读懂Presto如何与Alluxio搭配
linux下修改mysql用户名root
Practice of traffic recording and playback in vivo
"Jay bear" plummeted by 96.6%. Why is NFT with star goods cold?
Mysql57 zip file installation
How bacnet/ip gateway collects data of building centralized control system
Wechat applets - basics takes you to understand the life cycle of applets (I)
[C language] detailed explanation of C language to obtain array length
kubelet驱逐机制的源码分析
XML序列化向后兼容