这里为可带括号的四则运算求值,先转为逆波兰表达式,再解逆波兰表达式的值,解法具有可拓展性

    1. class ReversePolishNotation {
    2. public:
    3. ReversePolishNotation(string s) {
    4. if (!s.empty()) {
    5. transferToRePolish(s);
    6. computeReversePolish();
    7. }
    8. }
    9. private:
    10. //计算逆波兰表达式的值,栈的经典应用
    11. void computeReversePolish() {
    12. stack<float> stk;
    13. for (auto s : v) {
    14. if (!isOperator(s)) {
    15. stk.emplace(stof(s));
    16. }else {
    17. float y = stk.top();
    18. stk.pop();
    19. float x = stk.top();
    20. stk.pop();
    21. float num;
    22. if (s == "+") num = x + y;
    23. else if (s == "-") num = x - y;
    24. else if (s == "*") num = x*y;
    25. else num = x / y;
    26. stk.emplace(num);
    27. }
    28. }
    29. cout << stk.top() << endl;
    30. }
    31. //中缀表达式转换为逆波兰表达式,也是栈的经典应用
    32. //遍历到完整数字,追加到逆波兰表达式式尾
    33. //遍历到左括号入栈,遇到右括号,弹栈直到遇到左括号,把弹出的元素追加到逆波兰表达式式尾
    34. //遍历操作符ch,如果它的优先级小于等于栈顶操作符的优先级,则弹栈,把弹出的元素追加到逆波兰表达式式尾,
    35. //最后把该操作符ch压栈,维持栈顶优先级最高,维持一个递增栈。
    36. //遍历结束时,弹出所有的元素,并依次追加到逆波兰表达式式尾
    37. void transferToRePolish(const string& s) {
    38. int size = s.size();
    39. stack<char> stk;
    40. int i = 0;
    41. while (i < size) {
    42. if ((s[i] >= '0'&&s[i] <= '9') || s[i] == '.') {
    43. int j = i;
    44. while (s[i] >= '0'&&s[i] <= '9')
    45. i++;
    46. if (j - 1 >= 0 && (s[j - 1] == '-' || s[j - 1] == '+') && j - 2 >= 0 && s[j - 2] == '(') {
    47. stk.pop();
    48. v.emplace_back(s.substr(j - 1, i - j + 1));
    49. }
    50. else
    51. v.emplace_back(s.substr(j, i - j));
    52. }
    53. else if (s[i] == '(') {
    54. stk.push(s[i++]);
    55. }
    56. else if (s[i] == ')') {
    57. while (stk.top() != '(') {
    58. v.emplace_back(to_string(stk.top()));
    59. stk.pop();
    60. }
    61. stk.pop();
    62. i++;
    63. }else {
    64. while (!stk.empty() && priority(s[i]) <= priority(stk.top())) {
    65. v.emplace_back(to_string(stk.top()));
    66. stk.pop();
    67. }
    68. stk.emplace(s[i]);
    69. i++;
    70. }
    71. }
    72. while (!stk.empty()) {
    73. v.emplace_back(to_string(stk.top()));
    74. stk.pop();
    75. }
    76. }
    77. int priority(char ch) {
    78. switch (ch) {
    79. case '(': return 0;
    80. case '-':
    81. case '+': return 1;
    82. case '*':
    83. case '/': return 2;
    84. default: return -1;
    85. }
    86. }
    87. bool isOperator(const string& s) {
    88. return s.size() == 1 && string("+-*/").find(s[0]) != string::npos;
    89. }
    90. private:
    91. vector<string> v;
    92. };