关闭

LeetCode 224 Basic Calculator (后缀表达式 栈)

标签: leetcode后缀表达式
526人阅读 评论(0) 收藏 举报
分类:

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.

题目链接:https://leetcode.com/problems/basic-calculator/

题目分析:最中规中矩的做法就是,先中缀表达式转后缀表达式,然后根据后缀表达式计算答案,Java跑了100ms,算是很慢了,中缀转后缀的方法是:

1.若为数字直接加到后面

2.若为'(',入符号栈

3.若为运算符,则将优先级大于等于它的运算符先弹出并记录带答案,再将其入栈,本题运算符只有+,-,优先级相同

4.若为')',弹出运算符直到遇到‘(’

因为可能存在不止1位的数字,所以用一个空格来区分,还有就是连字符串的时候StringBuffer要比String快得多

public class Solution {
    
    public void solve(Stack<Integer> stkNum, char op) {
        int a = stkNum.peek();
        stkNum.pop();
        int b = stkNum.peek();
        stkNum.pop();
        if(op == '+') {
            stkNum.push(b + a);
        }
        else if(op == '-') {
            stkNum.push(b - a);
        }
    }
    
    public String infixToSuffix(String s) {
        StringBuffer sb = new StringBuffer("");
        Stack<Character> stkOp = new Stack<>();
        int num, len = s.length();
        for(int i = 0; i < len; i ++) {
            char ch = s.charAt(i);
            if(ch == ' ') {
                continue;
            }
            else if(ch == '(') {
                stkOp.push(ch);
            }
            else if(ch == '+' || ch == '-') {
                while(stkOp.size() > 0 && stkOp.peek() != '(') {
                    sb.append(stkOp.peek());
                    stkOp.pop();
                }
                stkOp.push(ch);
            }
            else if(ch == ')') {
                while(stkOp.peek() != '(') {
                    sb.append(stkOp.peek());
                    stkOp.pop();
                }
                stkOp.pop();
            }
            else {
                num = 0;
                while(i < len && s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                    sb.append(s.charAt(i));
                    i ++;
                }
                sb.append(' ');
                i --;
            }
        }
        return sb.toString();
    }
    
    public int calculate(String s) {
        Stack<Integer> stkNum = new Stack<>();
        String str = infixToSuffix('(' + s + ')');
        int num = 0;
        //System.out.println("str = " + str);
        for(int i = 0; i < str.length(); i ++) {
            if(str.charAt(i) == '+') {
                solve(stkNum, '+');
            }
            else if(str.charAt(i) == '-') {
                solve(stkNum, '-');
            }
            else {
                num = 0;
                while(str.charAt(i) != ' ') {
                    num = num * 10 + str.charAt(i) - '0';
                    i ++;
                }
                stkNum.push(num);
            }
        }
        return stkNum.peek();
    }
}

本题也可以不用栈,直接用递归解决递归的去处理每对括号,参考discuss里大神做法,短小精悍只跑了3ms

public class Solution {
    public static int calculate(String s) {
        if (s.length() == 0) {
            return 0;
        }
        s = "(" + s + ")";
        int[] pos = {0};
        return eval(s, pos);
    }

    private static int eval(String s, int[] pos) {
        int val = 0, i = pos[0], sign = 1, num = 0;
        while(i < s.length()) {
            char c = s.charAt(i);
            switch(c) {
                case '+': val = val + sign * num; num = 0; sign = 1; i++; break;
                case '-': val = val + sign * num; num = 0; sign = -1; i++; break;
                case '(': pos[0] = i + 1; val = val + sign * eval(s, pos); i = pos[0]; break;
                case ')': pos[0] = i + 1; return val + sign * num; 
                case ' ': i++; continue;
                default : num = num * 10 + c - '0'; i++;
            }
        }
        return val;
    }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:570027次
    • 积分:13439
    • 等级:
    • 排名:第955名
    • 原创:800篇
    • 转载:7篇
    • 译文:0篇
    • 评论:119条
    博客专栏