平常我们写的算术表达式:(3 + 4) * 5,运算顺序是:

  1. 先计算括号内的表达式,即(3+4),运算结果为7
  2. 计算7 * 5,结果为35

如果先写操作数,再写操作符,这个表达方式叫逆波兰表达式。上面的例子改写为逆波兰表达式为:3 4 + 5 *。要计算这样的表达式,先将+应用在34,得到7,然后化简7 5 *,为35

对于复杂的表达式,这会更加复杂,例如3 4 5 + *表示计算4 5 +(得到9),然后计算3 9 *,最终结果为27

逆波兰表达式的算法如下:

  1. If you read a number:
  2. Push it on the stack;
  3. Else if you read an operator:
  4. Pop 2 values off the stack;
  5. Combine the values with the opeator;
  6. Push the result back onto the stack;
  7. Else if there is no more input:
  8. Pop and display the result;

计算过程图如下:

1.jpg

Cpp 代码实现

  1. #include <iostream>
  2. #include <sstream>
  3. #include <stack>
  4. #include <string>
  5. #include <vector>
  6. static std::vector<std::string> split_string(std::string &input,
  7. char delimeter) {
  8. std::istringstream in(input); // turn string into input stream
  9. std::string tmp;
  10. std::vector<std::string> symbol_list;
  11. while (std::getline(in, tmp, ' ')) {
  12. symbol_list.push_back(tmp);
  13. }
  14. return symbol_list;
  15. }
  16. double reverse_polish_expression(std::string &input) {
  17. if (input.empty()) {
  18. std::fprintf(stderr, "EMPTY INPUT!\n");
  19. return 0;
  20. }
  21. // Split symbols by white space
  22. std::vector<std::string> symbol_list = split_string(input, ' ');
  23. std::stack<double> results;
  24. for (auto i : symbol_list) {
  25. char ch = *(i.c_str());
  26. if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
  27. // If the command is an operator,
  28. // pop the arguments and push the result
  29. if (results.size() < 2) {
  30. std::fprintf(stderr, "Insufficient arguments ");
  31. return 0;
  32. }
  33. // Note that the second argument is on the top of stack
  34. double arg2 = results.top();
  35. results.pop();
  36. double arg1 = results.top();
  37. results.pop();
  38. if (ch == '+') {
  39. results.push(arg1 + arg2);
  40. } else if (ch == '-') {
  41. results.push(arg1 - arg2);
  42. } else if (ch == '*') {
  43. results.push(arg1 * arg2);
  44. } else {
  45. if (arg2 == 0) {
  46. std::fprintf(stderr, "divisior cannt not be zero! ");
  47. return 0;
  48. }
  49. results.push(arg1 / arg2);
  50. }
  51. } else {
  52. // Not an operator --> push the input value
  53. if (ch == ' ') {
  54. continue;
  55. }
  56. results.push(std::stof(i));
  57. }
  58. }
  59. return results.top();
  60. }
  61. int main(int argc, char *argv[]) {
  62. std::string input;
  63. input = "3 4 + 5 *"; // output: 35
  64. std::cout << reverse_polish_expression(input) << std::endl;
  65. input = "3 4 5 + *"; // output: 27
  66. std::cout << reverse_polish_expression(input) << std::endl;
  67. input = "9 2 /"; // output: 4.5
  68. std::cout << reverse_polish_expression(input) << std::endl;
  69. input = "90 2 /"; // output: 45
  70. std::cout << reverse_polish_expression(input) << std::endl;
  71. input = "9 0 /"; // output: divisior cannt not be zero!
  72. std::cout << reverse_polish_expression(input) << std::endl;
  73. input = "3 5 + *"; // output: Insufficient arguments
  74. std::cout << reverse_polish_expression(input) << std::endl;
  75. return 0;
  76. }