LeetCode No.224 Basic Calculator 题解

来源:互联网 发布:手机淘宝怎么搜二手的 编辑:程序博客网 时间:2024/06/06 03:20

题目描述


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 .

You may assume that the given expression is always valid.

Some examples:

"1 + 1" = 2" 2-1 + 2 " = 3"(1+(4+5+2)-3)+(6+8)" = 23

Note: Do not use the eval built-in library function.


题目分析

题目大意就是做一个简单的Calculator,完成简单的+,-,(,)的运算。
很明显又是一个 Hard 的水题。
直接用数据结构的栈即做完之后可秒杀之。
作为题解还是稍微解释一下吧。
遍历一遍字符串,根据不同的字符来不同处理。 具体如下:
* 若是(,直接入符号栈。
* 若是+, -, 弹出栈顶之前的所有+,-,并取操作数出来进行运算。 最后把该符号压入符号栈。
* 若是),弹出栈顶并计算之直到栈顶为(,最后弹出(
* 若是backspace, 不处理
* 若是其他(保证合法的情况下,只可能是数字了),对字符串分析取出整个数字(有可能不止一位),并压入数字栈。
* 遍历完成之后, 若符号栈还有符号,取出运算即可。

大概做法如上。
但是关键在于程序进行模块化的时候如何不超时是一个问题。当然若是只是写在一个函数中(不用其他辅助函数的话) 没这个问题。
我用的C++, 相对起来处理起来方便一点。 其一是不用考虑字符串的长度用string即可。传入参数的时候尽量采用引用传递。特别是对“`stack, string““这种需要调用构造函数的类型。

下面是具体代码。注意只要任何一个地方不加引用传递就会超时。


#include <stack>#include <iostream> using namespace std;class Solution {public:    int calculate(string s) {        stack<char> ope;        stack<int> num;        int i = 0, ans = 0;        while (i < s.size()) {            switch(s[i]) {                case '(':                     ope.push(s[i]);                    break;                case ')':                    bracket_pop(ope, num);                    break;                case '+':                    ope_pop(ope, num, '+');                    break;                case '-':                    ope_pop(ope, num, '-');                    break;                case ' ':                    break;                    //do nothing;                default:                    //number                    push_num(s, i, num);                    break;            }            ++i;        }            if (!ope.empty()) {                ope_pop(ope, num, '#');            }            return num.top();        }        inline void bracket_pop(stack<char> &ope, stack<int> &num) {            while (ope.top() != '(') {                ope_pop(ope, num, '#');            }            ope.pop();        }        inline void ope_pop(stack<char> &ope, stack<int> &num, char x) {            if (ope.empty() || ope.top() == '(' ) {                ope.push(x);            return;        }        int num2 = num.top();        num.pop();        int num1 = num.top();        num.pop();        if (ope.top() == '+') {            num.push(num1 + num2);        }         else {            num.push(num1 - num2);        }        ope.pop();        if (x != '#')            ope.push(x);        return;    }    inline void push_num(string &s, int &i, stack<int> &num) {        int k = 0;        while (s[i] >= '0' && s[i] <= '9') {            k = k * 10 + (s[i] - '0');            i++;        }        i--;        num.push(k);        return;    }};

其他细节

  • 这道题只要求+, -的处理。 事实上很多地方并不需要用到while,因为一定只会弹出一次。
  • 即使用inline函数和引用传递, 调用函数还是要一定的时间开销的。 如果要保证效率还是写在一个函数中比较好。

The End.

原创粉丝点击