• 【c++】逆波兰表达式求值(详解)


    逆波兰表达式求值

    题述:

    什么叫逆波兰表达式?

    其又称后缀表达式 ,而中缀表达式操作数在两边,操作符在中间的表达式,但中缀表达式不方便机器运算的,比如4 + 13 / 5是一个中缀表达式,但机器是从左往右依次读取的,他都不考虑优先级,所以一定会出错,所以要把中缀表达式转为后缀表达式

    4 + 13 / 5 转为后缀表达式-> 4 13 5 / +

    后缀表达式特点:

    操作数顺序不变,操作符在操作数的后边,并且按优先级排列,后缀表达式又称为逆波兰表达式

    对于表达式的计算,两步走:

    1、中缀表达式转为后缀表达式

    2、后缀表达式的运算

    而本题考察的就是第二点了

    思路:

     操作数入栈,遇到操作符取两个数据出栈,怎么判断是不是操作符还是操作数?操作符就+ - * /,列出来即可,那取两个数据的顺序如何?栈的特性:先进后出,因为运算是从左往右算的,那么右操作数一定是后入栈的,所以先出的作为右操作数,紧接着再取出的操作数作为左操作数运算完结果还要入栈,因为要连续运算保存结果,每次都是在上一次的运算结果上继续运算

    操作数入栈前要把字符串转换为整形,因为转换为整形才能直接运算

    string有个把字符串转为整形的成员函数 stoi

    代码如下(测试通过):

    1. //逆波兰表达式求值
    2. class Solution {
    3. public:
    4. int evalRPN(vector& tokens) {
    5. stack<int> st;//栈用来入操作数,故应为int,涉及字符串转换为int的操作
    6. for (auto& str : tokens)
    7. {
    8. //1、操作符取栈数据进行运算
    9. //2、操作数入栈
    10. if (str == "+" || str == "-" || str == "*" || str == "/")
    11. {
    12. int right = st.top();//先出栈的应该放在操作符右边
    13. st.pop();
    14. int left = st.top();
    15. st.pop();
    16. //switch的判断条件不能是自定义类型,因为他不支持自定义类型
    17. //switch (str)
    18. //{
    19. //case "+":
    20. //}
    21. //switch条件是字符可以,switch只能用内置类型做条件,自定义类型不行
    22. switch (str[0])
    23. {//str是string,str[0]是利用operator[]取对应字符,传入要么是
    24. //一个数,要么是一个运算符,所以访问第一个字符就取到对应string的内容了
    25. case '+':
    26. st.push(left + right);//把运算出的结果入栈
    27. break;
    28. case '-':
    29. st.push(left - right);
    30. break;
    31. case '*':
    32. st.push(left * right);
    33. break;
    34. case '/':
    35. st.push(left / right);
    36. break;
    37. }
    38. }
    39. else
    40. {
    41. st.push(stoi(str));//是操作数就先转为整数再入栈
    42. }
    43. }
    44. return st.top();//最后栈中剩下的一个值就是表达式的结果
    45. }
    46. };

     问题解释:

    1、遇到操作符会遇到没操作数的情况?

    遇到操作符不可能没操作数,因为后缀表达式都是操作数在前,操作符在后,要不然就不是后缀表达式了

    2、代码中str[0]是什么意思?

    str是string类型的,而str[0],调用了string的operator[],其返回字符,因为本题每个string类型的对象都是存一个字符串一个操作数,比如"+","2",而str[0]后,(假设第一个string对象存的是“+”)得到的是‘+’,也就是变成了一个字符,switch的条件起码是个内置类型才能支持,自定义类型不能支持


    补充知识(中缀转后缀表达式):

    了解中缀转后缀的过程(要调整的就是操作符的顺序):

    1、操作数直接输出,不动

    2、操作符入栈,操作符要通过比较确定计算顺序

    ①、栈为空,操作符入栈

    ②、栈不为空,操作符比栈顶的优先级高,入栈

    ③、栈不为空,操作符等于或低于当前栈顶操作符的优先级,则出栈顶的运算符,然后再入此时的操作符(比如栈顶为*,此时要入+,那么就先出*,然后再入+)

    ④、遇到)直接入栈,直到遇到操作符是(,此时会一直把栈中数据出栈直到遇到左括号(

    ⑤、最后栈中剩余的操作符会依次出栈

    本质上其实就是看相邻运算符的优先级,优先级高的先运算,所以有第③点

    了解即可,中缀表达式转为后缀表达式,一般不怎么考,但是选择题可能会出现


  • 相关阅读:
    面试题常考:LRU缓存
    ElasticSearch 使用 searchAfter() 进行遍历查询 查到的数据总数小于 totalHits
    基于 Kubernetes 部署 Zookeeper(StatefulSet方式)
    多线程学习笔记(一)
    无多余电源工业环境如何实现远程维护
    快速入门C++第七天——输入与输出
    Vue——组件高级——传值
    ETCD详解
    ASP.NET预约洗车小程序源码(前台+后台)
    性能优化:TCP连接优化之三次握手
  • 原文地址:https://blog.csdn.net/m0_74044018/article/details/132838231