实现基础计算器--Basic Calculator

题目:

Basic Calculator:

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .


思考:

  1、首先分析题意,题目要求计算表达式值,首先想到的就是使用栈存储表达式,可先通过处理运算符将原表达式转化为后缀式,进而通过优先级计算后缀式,得到结果

  2、但是仔细分析,可以发现,本题不需要将原式转化为后缀式求解。表达式中只包含非负整数,括号,+,-,以及空格。并不存在运算优先级的问题,只需要处理括号即可。

具体思路:

  建立两个栈,分别为char,int,存储表达式中的运算符,和数字。用字符串s存储表达式,s尾部添加'#',表示结束,从头开始扫描s[i]:

  • s[i]为' ',不作操作。
  • s[i]为'(',进栈。
  • s[i]为'+','-',判断运算符栈顶是否为空,或是否为'(',若不是则将数字栈的前两个元素弹出,将运算符栈弹出,进行运算,运算结果入栈,s[i]入栈。
  • s[i]为')',将'('前的运算符弹出计算。
  • s[i]为数字,将下一个运算符前的数字一同计算,结果压入栈。
  • s[i]为'#',判断运算符栈是否为空,不为空,再弹栈进行计算,得到结果。

代码:

  1 #include 
  2 #include 
  3 #include <string>
  4 using namespace std;
  5 
  6 class Solution 
  7 {
  8 public:
  9     int calculate(string s) 
 10     {
 11         stack<int> numbers;
 12         stack<char> ops;
 13         s.push_back('#');                      //插入终止符'#'
 14         for (int i = 0;i < s.length();i++)     //依次扫描字符串s
 15         {
 16             switch (s[i])
 17             {
 18             case ' ':
 19                 break;
 20             case '(':
 21                 ops.push(s[i]); 
 22                 break;
 23             case ')':
 24                 while (ops.top() != '(')
 25                 {
 26                     int num_1, num_2;
 27                     char temp_op;
 28                     num_2 = numbers.top();
 29                     numbers.pop();
 30                     num_1 = numbers.top();
 31                     numbers.pop();
 32                     temp_op = ops.top();
 33                     ops.pop();
 34                     numbers.push(calculating(num_1, num_2, temp_op));
 35                 }
 36                 ops.pop();
 37                 break;
 38             case '#':
 39                 if (!ops.empty())
 40                 {
 41                     int num_1, num_2;
 42                     char temp_op;
 43                     num_2 = numbers.top();
 44                     numbers.pop();
 45                     num_1 = numbers.top();
 46                     numbers.pop();
 47                     temp_op = ops.top();
 48                     ops.pop();
 49                     numbers.push(calculating(num_1, num_2, temp_op));
 50                 };
 51                 break;
 52             case '+':
 53             case '-':
 54                 if (!ops.empty())
 55                 {
 56                     if (ops.top() != '(')
 57                     {
 58                         int num_1, num_2;
 59                         char temp_op;
 60                         num_2 = numbers.top();
 61                         numbers.pop();
 62                         num_1 = numbers.top();
 63                         numbers.pop();
 64                         temp_op = ops.top();
 65                         ops.pop();
 66                         numbers.push(calculating(num_1, num_2, temp_op));
 67                     }
 68                 }
 69                 ops.push(s[i]);
 70                 break;
 71             default:                                    //处理s[i]为数字的情况
 72                 int temp_answer = s[i] - '0';
 73                 while (isDigit(s[i + 1]))
 74                 {
 75                     temp_answer = temp_answer * 10 + s[++i] - '0';
 76                 }
 77                 numbers.push(temp_answer);
 78                 break;
 79             }
 80         }
 81         return numbers.top();
 82     }
 83     bool isDigit(char a)                               //判断字符是否为'0'-'9'
 84     {
 85         if (a >= '0' && a <= '9')
 86         {
 87             return true;
 88         }
 89         else
 90         {
 91             return false;
 92         }
 93     }
 94     int calculating(int num1, int num2, char op)      //加减计算
 95     {
 96         switch (op)
 97         {
 98         case '+':
 99             return num1 + num2;
100             break;
101         default:
102             return num1 - num2;
103             break;
104         }
105     }
106 };
107 
108 int main()
109 {
110     Solution solution;
111     string s;
112     cin >> s;
113     cout << solution.calculate(s) << endl;
114     return 0;
115 }

进一步思考,当s结束时,需要再次判断数字栈是否为空,较为麻烦,可以在运算符栈先压入'(',且在字符串s后加')',则当s[i]为最后的')'时,可将运算符栈最底端'('之前的运算符都弹出计算,代码更加清晰简短。

代码如下:

  1 #include 
  2 #include 
  3 #include <string>
  4 using namespace std;
  5 
  6 
  7 
  8
  9 class Solution
 10 {
 11 public:
 12     int calculate(string s)
 13     {
 14         stack<int> numbers;
 15         stack<char> ops;
 16         ops.push('(');
 17         s.push_back(')');
 18         for (int i = 0; i < s.length(); i++)
 19         {
 20             switch (s[i])
 21             {
 22             case ' ':
 23                 break;
 24             case '(':
 25                 ops.push(s[i]);
 26                 break;
 27             case ')':
 28                 while (ops.top() != '(')
 29                 {
 30                     int num_1, num_2;
 31                     char temp_op;
 32                     num_2 = numbers.top();
 33                     numbers.pop();
 34                     num_1 = numbers.top();
 35                     numbers.pop();
 36                     temp_op = ops.top();
 37                     ops.pop();
 38                     numbers.push(calculating(num_1, num_2, temp_op));
 39                 }
 40                 ops.pop();
 41                 break;
 42             case '+':
 43             case '-':
 44                 if (!ops.empty() && ops.top() != '(')
 45                 {
 46                     int num_1, num_2;
 47                     char temp_op;
 48                     num_2 = numbers.top();
 49                     numbers.pop();
 50                     num_1 = numbers.top();
 51                     numbers.pop();
 52                     temp_op = ops.top();
 53                     ops.pop();
 54                     numbers.push(calculating(num_1, num_2, temp_op));
 55                 }
 56                 ops.push(s[i]);
 57                 break;
 58             default:
 59                 int temp_answer = s[i] - '0';
 60                 while (isDigit(s[i + 1]))
 61                 {
 62                     temp_answer = temp_answer * 10 + s[++i] - '0';
 63                 }
 64                 numbers.push(temp_answer);
 65                 break;
 66             }
 67         }
 68         return numbers.top();
 69     }
 70     bool isDigit(char a)
 71     {
 72         if (a >= '0' && a <= '9')
 73         {
 74             return true;
 75         }
 76         else
 77         {
 78             return false;
 79         }
 80     }
 81     int calculating(int num1, int num2, char op)
 82     {
 83         switch (op)
 84         {
 85         case '+':
 86             return num1 + num2;
 87             break;
 88         default:
 89             return num1 - num2;
 90             break;
 91         }
 92     }
 93 };
 94 
 95 
 96 int main()
 97 {
 98     Solution solution;
 99     string s;
100     cin >> s;
101     cout << solution.calculate(s) << endl;
102     return 0;
103 }

总结:

  这个题目较为简单,只包含'+','-',' ','(',')',无需求后缀式,可简化程序。此算法只进行了一次扫描,时间复杂度为o(n),使用两个栈存储,空间复杂度为o(n),但此方法缺点是可扩展性较差,只适用于这个题目。

 此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是[email protected]

转载于:https://www.cnblogs.com/Jueis-lishuang/p/4895860.html

你可能感兴趣的:(实现基础计算器--Basic Calculator)