• 4.从中缀向后缀转换表达式


    目录

    题目

    输入

    输出

    思路

    注意事项

    C++完整代码


    题目

    问题描述

      中缀表达式就是我们通常所书写的数学表达式,后缀表达式也称为逆波兰表达式,在编译程序对我们书写的程序中的表达式进行语法检查时,往往就可以通过逆波兰表达式进行。我们所要设计并实现的程序就是将中缀表示的算术表达式转换成后缀表示,例如,将中缀表达式

    (A 一 (B*C 十 D)*E) / (F 十 G )

    转换为后缀表示为:

    ABC*D十E*--FG十/

    注意:为了简化编程实现,假定变量名均为单个字母,运算符只有+,-,*,/ 和^(指数运算),可以处理圆括号(),并假定输入的算术表达式正确。

    要求:使用栈数据结构实现 ,输入的中缀表达式以#号结束

    输入

    整数N。表示下面有N个中缀表达式
    N个由单个字母和运算符构成的表达式

    输出

    N个后缀表达式


    思路

    1. 遍历中缀表达式的每个字符。
    2. 如果当前字符是字母,直接将其添加到后缀表达式中。
    3. 如果当前字符是左括号或指数运算符(^),直接入栈。
    4. 如果当前字符是右括号,将栈中的运算符出栈并添加到后缀表达式中,直到遇到左括号为止。然后再将左括号出栈。
    5. 如果当前字符是运算符,将栈中的运算符出栈并添加到后缀表达式中,直到栈为空或栈顶元素为左括号,或当前运算符的优先级小于等于栈顶运算符的优先级。然后将当前运算符入栈。
    6. 遍历完中缀表达式后,将栈中剩余的运算符全部出栈并添加到后缀表达式中。

     

    注意事项

    1. 代码中使用了函数 isOperator 来判断一个字符是否是运算符,以及函数 getPrecedence 来获取运算符的优先级。
    2. 代码使用了 stack 类来实现栈的功能,用于存储运算符。
    3. 在读取中缀表达式之前,需要先读取要转换的中缀表达式的个数,并且在每次读取中缀表达式后要忽略换行符。
    4. 代码中使用了 getline(cin, infix, '#') 来以 '#' 作为结束符读取中缀表达式。
    5. 左括号和指数运算符在中缀表达式转换为后缀表达式的过程中具有不同的特殊性质,因此它们在处理时需要特殊对待。

      ①左括号:
      左括号在中缀表达式中用于标识一个子表达式的开始,它的作用是改变运算符的优先级。在中缀表达式转换为后缀表达式的过程中,左括号在遇到右括号之前应该保留在栈中,以确保对应的子表达式被正确处理。因此,左括号在遇到时直接入栈。

      ②指数运算符(^):
      指数运算符在运算符中具有最高的优先级,它通常是右结合的(即指数运算符之间按照右结合的顺序进行运算)。为了在后缀表达式中正确表示指数运算符的运算顺序,我们需要将指数运算符与其他运算符区分开来,并确保它们在计算顺序上的正确性。因此,指数运算符在遇到时也直接入栈。

      总之,左括号和指数运算符在中缀表达式转换为后缀表达式的过程中需要被特殊处理,它们需要优先级高于其他运算符,并在栈中保持相对应的位置,以确保后续的处理和计算的正确性。

    6. 注意处理右括号时,需要将栈中的运算符依次出栈并添加到后缀表达式中,直到遇到左括号。
    7. 在最终输出后缀表达式之前,要将栈中剩余的运算符全部出栈并添加到后缀表达式中。

    C++完整代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. // 判断字符是否是运算符
    6. bool isOperator(char c) {
    7. return c == '+' || c == '-' || c == '*' || c == '/' || c == '^';
    8. }
    9. // 获取运算符的优先级
    10. int getPrecedence(char c) {
    11. if (c == '^') {
    12. return 3;
    13. }
    14. else if (c == '*' || c == '/') {
    15. return 2;
    16. }
    17. else if (c == '+' || c == '-') {
    18. return 1;
    19. }
    20. }
    21. // 将中缀表达式转换为后缀表达式
    22. string infixToPostfix(const string& infix) {
    23. stack<char> stk; // 用于存储运算符的栈
    24. string postfix; // 存储后缀表达式的字符串
    25. for (char c : infix) {
    26. if (isalpha(c)) { // 判断是否为字母
    27. postfix += c; // 将字母直接添加到后缀表达式中
    28. }
    29. else if (c == '(' || c == '^') { // 左括号和指数运算符直接入栈
    30. stk.push(c);
    31. }
    32. else if (c == ')') { // 遇到右括号时,将栈中的运算符出栈并添加到后缀表达式中,直到遇到左括号为止
    33. while (!stk.empty() && stk.top() != '(') {
    34. postfix += stk.top();
    35. stk.pop();
    36. }
    37. stk.pop(); // 弹出左括号
    38. }
    39. else if (isOperator(c)) { // 如果是运算符
    40. while (!stk.empty() && stk.top() != '(' && getPrecedence(c) <= getPrecedence(stk.top())) {
    41. // 当栈不为空,栈顶元素不是左括号,并且当前运算符的优先级小于等于栈顶运算符的优先级时
    42. postfix += stk.top(); // 将栈顶运算符出栈并添加到后缀表达式中
    43. stk.pop();
    44. }
    45. stk.push(c); // 当前运算符入栈
    46. }
    47. }
    48. // 将栈中剩余的运算符全部出栈并添加到后缀表达式中
    49. while (!stk.empty()) {
    50. postfix += stk.top();
    51. stk.pop();
    52. }
    53. return postfix;
    54. }
    55. int main() {
    56. int N;
    57. cin >> N; // 输入要转换的中缀表达式的个数
    58. for (int i = 0; i < N; i++) {
    59. string infix;
    60. getline(cin, infix, '#'); // 以'#'作为结束符,读取中缀表达式
    61. cin.ignore(); // 忽略读取中缀表达式后的换行符
    62. string postfix = infixToPostfix(infix); // 调用函数将中缀表达式转换为后缀表达式
    63. cout << postfix << endl; // 输出后缀表达式
    64. }
    65. return 0;
    66. }

  • 相关阅读:
    研究生期间工作记录
    A Survey on Neural Network Interpretability
    JavaScript基础知识整理
    ACL2022国内部分论文分享内容总结1
    ElasticSearch中实际操作细节点
    如何使用SOLIDWORKS添加装饰螺纹线规格
    野火A7学习第九次(流水灯和呼吸灯相关)
    echarts静态横向柱状图
    pcd点云格式介绍
    面试系列Spring:Spring的事务传播
  • 原文地址:https://blog.csdn.net/m0_74200772/article/details/133497006