中缀表达式转后缀表达式的方法

    1. 如果遇到操作数,将其添加到后缀表达式的后面;
    2. 如果遇到操作符:
    • 操作符栈为空时,操作符入栈;
    • 遇到左括号时,左括号入栈(无论操作符栈是否为空);
    • 遇到右括号时,依次弹出栈中的操作符(添加到后缀表达式中的后面),直到遇到左括号(弹出左括号),左右括号均不添加到后缀表达式中;
    • 遇到其他运算符时,依次弹出栈中优先级高于或等于当前操作符高的操作符(添加到后缀表达式后面),或者遇到左括号时停止,然后将当前操作符入栈;
    1. 将操作符栈中的元素依次弹出(添加到后缀表达式中的后面)。

    优先级可视为:* />+ ->(

    示例:
    中缀表达式1-2*3+(4*(5-6)+7)/8+9 转变为后缀表达式1 2 3 * - 4 5 6 - * 7 + 8 / + 9 +

    1. 初始状态
    • 操作符栈为[],后缀表达式为""
    1. 遇到操作数1,添加到后缀表达式中
    • 操作符栈为[],后缀表达式为"1"
    1. 遇到操作符-,此时操作符栈为空,直接入栈
    • 操作符栈为[-],后缀表达式为"1"
    1. 遇到操作数2,添加到后缀表达式中
    • 操作符栈为[-],后缀表达式为"1 2"
    1. 遇到操作符*,栈中无比*优先级高或相同的操作符,无需弹出,最后将该操作符入栈
    • 操作符栈为[- *],后缀表达式为"1 2"
    1. 遇到操作数3,添加到后缀表达式中
    • 操作符栈为[- *],后缀表达式为"1 2 3"
    1. 遇到操作符+,弹出栈中比+优先级高或相同的操作符* -添加到后缀表达式中,最后+入栈
    • 操作符栈为[+],后缀表达式为"1 2 3 * -"
    1. 遇到左括号(,入栈
    • 操作符栈为[+ (],后缀表达式为"1 2 3 * -"
    1. 遇到操作数4,追加到后缀表达式中
    • 操作符栈为[+ (],后缀表达式为"1 2 3 * - 4"
    1. 遇到操作符*,弹出栈中优先级高于或等于*的(但栈顶为左括号,无需弹出),最后*入栈
    • 操作符栈为[+ ( *],后缀表达式为"1 2 3 * - 4"
    1. 遇到左括号(,左括号入栈
    • 操作符栈为[+ ( * (],后缀表达式为"1 2 3 * - 4"
    1. 遇到操作数5,添加到后缀表达式中
    • 操作符栈为[+ ( * (],后缀表达式为"1 2 3 * - 4 5"
    1. 遇到操作符-,弹出栈中优先级高于或等于-的(但栈顶为左括号,无需弹出),最后-入栈
    • 操作符栈为[+ ( * ( -],后缀表达式为"1 2 3 * - 4 5"
    1. 遇到操作数6,添加到后缀表达式中
    • 操作符栈为[+ ( * ( -],后缀表达式为"1 2 3 * - 4 5 6"
    1. 遇到右括号),依次弹出栈中操作符,直到遇到左括号,左右括号均不添加到后缀表达式中
    • 操作符栈为[+ ( *],后缀表达式为"1 2 3 * - 4 5 6 -"
    1. 遇到操作符+,弹出栈中优先级高于或等于+的(*),最后+入栈
    • 操作符栈为[+ ( +],后缀表达式为"1 2 3 * - 4 5 6 - *"
    1. 遇到操作数7,添加到后缀表达式中
    • 操作符栈为[+ ( +],后缀表达式为"1 2 3 * - 4 5 6 - * 7"
    1. 遇到右括号),依次弹出栈中操作符,直到遇到左括号,左右括号均不添加到后缀表达式中
    • 操作符栈为[+],后缀表达式为"1 2 3 * - 4 5 6 - * 7 +"
    1. 遇到除号/,弹出栈中优先级高于或等于/的(无),最后/入栈
    • 操作符栈为[+ /],后缀表达式为"1 2 3 * - 4 5 6 - * 7 +"
    1. 遇到操作数8,添加到后缀表达式中
    • 操作符栈为[+ /],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8"
    1. 遇到操作符+,弹出栈中优先级高于或等于+的(/ +),最后+入栈
    • 操作符栈为[+],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8 / +"
    1. 遇到操作数9,添加到后缀表达式中
    • 操作符栈为[+],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8 / + 9"
    1. 依次弹出栈中剩余元素
    • 操作符栈为[],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8 / + 9 +"

    结束

    1. class Solution {
    2. public:
    3. /**
    4. * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    5. * 返回表达式的值
    6. * @param s string字符串 待计算的表达式
    7. * @return int整型
    8. */
    9. int solve(string s) {
    10. // write code here
    11. vector<string> infOrder, sufOrder;
    12. this->strParser(s, infOrder);
    13. printVector(infOrder);
    14. this->infill2suffix(infOrder, sufOrder);
    15. printVector(sufOrder);
    16. return this->suffix2val(sufOrder);
    17. }
    18. int suffix2val(vector<string>& sufOrder){
    19. // 后缀表达式求值
    20. stack<int> numStack;
    21. int a, b;
    22. for(string str : sufOrder){
    23. if(isOperator(str)){
    24. b = numStack.top();
    25. numStack.pop();
    26. a = numStack.top();
    27. numStack.pop();
    28. if(str == "+"){
    29. numStack.push(a + b);
    30. }else if(str == "-"){
    31. numStack.push(a - b);
    32. }else if(str == "*"){
    33. numStack.push(a * b);
    34. }else{
    35. numStack.push(a / b);
    36. }
    37. }
    38. else{
    39. numStack.push(atoi(str.c_str()));
    40. }
    41. }
    42. return numStack.top();
    43. }
    44. void infill2suffix(vector<string>& infOrder, vector<string>& sufOrder){
    45. // 中缀表达式转后缀表达式
    46. sufOrder.clear();
    47. stack<string> opStack;
    48. for(string str : infOrder){
    49. if(isOperator(str)){
    50. if(opStack.empty() || str=="("){
    51. opStack.push(str);
    52. }
    53. else if(str == ")"){
    54. while(opStack.top() != "("){
    55. sufOrder.push_back(opStack.top());
    56. opStack.pop();
    57. }
    58. opStack.pop();
    59. }
    60. else{
    61. while(!opStack.empty() && isHigherOperator(opStack.top(), str)){
    62. sufOrder.push_back(opStack.top());
    63. opStack.pop();
    64. }
    65. opStack.push(str);
    66. }
    67. }
    68. else{
    69. sufOrder.push_back(str);
    70. }
    71. }
    72. while(!opStack.empty()){
    73. sufOrder.push_back(opStack.top());
    74. opStack.pop();
    75. }
    76. }
    77. void strParser(string& s, vector<string>& ret){
    78. // 解析字符串,将数字和符号分开
    79. string curStr = "";
    80. for(char ch : s){
    81. if(ch >= '0' && ch <= '9'){
    82. curStr += ch;
    83. }
    84. else{
    85. if(curStr != ""){
    86. ret.push_back(curStr);
    87. }
    88. ret.push_back(string(1, ch));
    89. curStr = "";
    90. }
    91. }
    92. if(curStr != ""){
    93. ret.push_back(curStr);
    94. }
    95. }
    96. bool isOperator(string& op){
    97. for(int i=0; i<this->ops.size(); i++){
    98. if(op == this->ops[i]){
    99. return true;
    100. }
    101. }
    102. return false;
    103. }
    104. bool isHigherOperator(string& op1, string& op2){
    105. // 判断op1是否比op2的优先级较高
    106. return this->opsPriority[op1] >= this->opsPriority[op2];
    107. }
    108. private:
    109. vector<string> ops={"+", "-", "*", "/", "(", ")"};
    110. map<string, int> opsPriority = {
    111. {"(", 0},
    112. {"+", 1}, {"-", 1},
    113. {"*", 2}, {"/", 2}
    114. };
    115. };