题解 | #表达式求值#

表达式求值

http://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4

1.先转换为后缀表达式
2.再用力扣150表达式求值计算

public class Solution {

    // Q:请写一个整数计算器,支持加减乘三种运算和括号
    public int solve(String s) {
        return evalRPN(toSuffix(s));
    }

    // 中缀表达式转换为后缀表达式
    // a+b -> ab+
    // (2*(3-4))*5 -> 234-*5*
    private String[] toSuffix(String s) {
        HashMap<Character, Integer> map = new HashMap<>();
        map.put('(', 0);
        map.put('+', 1);
        map.put('-', 1);
        map.put('*', 2);
        map.put('/', 2);
        // 存数字和最后的后缀表达式
        LinkedList<String> queue = new LinkedList<>();
        // 栈存运算符
        LinkedList<Character> stack = new LinkedList<>();
        char[] cs = s.trim().toCharArray();
        String standard = "+-*/()";
        char ch;
        int len = 0;// 记录加入queue中的表达式长度
        for (int i = 0; i < cs.length; i++) {
            ch = cs[i];
            if (Character.isDigit(ch) || Character.isLetter(ch) || ch == '.') {// 遇到数字/字母/小数点,len++
                len++;
            } else if (Character.isSpaceChar(ch)) {// 遇到空格
                if (len > 0) {
                    queue.add(String.valueOf(Arrays.copyOfRange(cs, i - len, i)));
                    len = 0;
                }
                continue;
            } else if (standard.contains(String.valueOf(ch))) {// 遇到+-*/()这6种表达式
                if (len > 0) {
                    queue.add(String.valueOf(Arrays.copyOfRange(cs, i - len, i)));
                    len = 0;
                }
                if (ch == '(') {// 遇见(先入栈
                    stack.push(ch);
                    continue;
                }
                if (!stack.isEmpty()) {// 如果栈不为空,说明之前存了其他运算符,需要出栈
                    boolean flag = false;
                    // 如ch为),则一直出栈直到遇到(
                    while (!stack.isEmpty() && ch == ')' && stack.peek() != '(') {
                        queue.add(String.valueOf(stack.pop()));
                        flag = true;//设置标志位,标记取的是()中的元素
                    }
                    // 如果不是去()中的元素
                    while (!stack.isEmpty() && !flag && map.get(stack.peek()) >= map.get(ch)) {
                        queue.add(String.valueOf(stack.pop()));
                    }
                }
                if (ch != ')') {
                    stack.push(ch);
                } else {
                    stack.pop();
                }
            }
            if (i == cs.length - 1) {
                if (len > 0) {// 如果走到中缀表达式最后一位,len>0说明遇到数字,放入queue中
                    queue.add(String.valueOf(Arrays.copyOfRange(cs, i - len + 1, i + 1)));
                }
                while (!stack.isEmpty()) {
                    queue.add(String.valueOf(stack.pop()));
                }
            }
        }
        // 返回字符串数组
        return queue.toArray(new String[0]);
    }

    // 力扣150后缀表达式求值
    public int evalRPN(String[] tokens) {
        int[] stack = new int[tokens.length];
        // 数组stack从0开始,初始化i=-1
        int i = -1;
        for (String s : tokens) {
            if ("+-*/".contains(s)) {
                int b = stack[i--];// 先出栈的是操作数2
                int a = stack[i--];// 后出栈的是操作数1
                stack[++i] = calculate(a, b, s);
            } else {
                stack[++i] = Integer.parseInt(s);
            }
        }
        // 遍历完tokens字符数组,stack中只剩一个数字,就是结果
        return stack[i];
    }

    private int calculate(int a, int b, String op) {
        if ("+".equals(op)) {
            return a + b;
        } else if ("-".equals(op)) {
            return a - b;
        } else if ("*".equals(op)) {
            return a * b;
        } else if ("/".equals(op)) {
            return a / b;
        }
        return -1;
    }
}
全部评论

相关推荐

10-05 11:11
海南大学 Java
投票
理想江南137:感觉挺真诚的 感觉可以试一试
点赞 评论 收藏
分享
拉丁是我干掉的:把上海理工大学改成北京理工大学。成功率增加200%
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务