题解 | #表达式求值#

表达式求值

https://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d

import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String exp = in.next();
            int length = exp.length();
            //运算符栈
            Stack<Character> op = new Stack<>();
            //操作数栈
            Stack<Integer> data = new Stack<>();
            for (int i = 0; i < length; i++) {
                char ch = exp.charAt(i);
                if (ch >= '0' && ch <= '9') {
                    //数字完全截取
                    int index = i;
                    while (index != length - 1) {
                        if (exp.charAt(index) >= '0' && exp.charAt(index) <= '9') {
                            //指针后移
                            index++;
                        } else {
                            //退出循环
                            break;
                        }
                    }
                    //截取字符
                    String s = "";
                    if (i != length - 1) {
                        s = exp.substring(i, index);
                    } else {
                        s = exp.substring(index, length);
                    };
                    int num = Integer.parseInt(s);
                    data.push(num);
                    if (i != length - 1) {
                        //下标跳过
                        i = index - 1;
                    }
                    //下一次循环
                    continue;
                } else if (op.isEmpty() || ch == '(') {
                    if (ch == '+' || ch == '-') {
                        //对正负号,如果前一个字符不是数字或者没有字符,因给操作数0
                        if (i - 1 < 0 || exp.charAt(i - 1) == '(') {
                            //增加操作数0
                            data.push(0);
                        }
                    }
                    op.push(ch);
                } else if (ch == ')') {
                    while (op.peek() != '(') {
                        compute(data, op);
                    }
                    char wasted = op.pop();
                } else if (ch == '+' || ch == '-') {
                    while (!op.isEmpty() && op.peek() != '(') {
                        compute(data, op);
                    }
                    //对正负号,如果前一个字符不是数字或者没有字符,因给操作数0
                    if (i - 1 < 0 || exp.charAt(i - 1) == '(') {
                        //增加操作数0
                        data.push(0);
                    }
                    op.push(ch);
                } else if (ch == '*' || ch == '/') {
                    //看栈顶元素是否为乘号或者除号
                    if (op.peek() == '+' || op.peek() == '-') {
                        op.push(ch);
                    } else {
                        //是乘号或者除号
                        while (!op.isEmpty() && op.peek() != '(' && op.peek() != '-' &&
                                op.peek() != '+') {
                            compute(data, op);
                        }
                        op.push(ch);
                    }
                }
            }
            if (!op.isEmpty()) {
                //运算符栈不为空,继续计算
                while (!op.isEmpty()) {
                    compute(data, op);
                }
            }
            System.out.println(data.peek());
        }
    }
    public static void compute(Stack<Integer> data, Stack<Character> op) {
        char operator = op.pop();
        int right = data.pop();
        int left = data.pop();
        int res = -1;
        if (operator =='+') {
            res = left + right;
        } else if (operator == '-') {
            res = left - right;
        } else if (operator == '*') {
            res = left * right;
        } else {
            res = left / right;
        }
        data.push(res);
    }
    public static int charToInt(char ch) {
        int res = Integer.parseInt(Character.toString(ch));
        return res;
    }
}

个人认为,如果内部逻辑太多,使用递归极其不易懂(高赞答案看的我脑瓜疼)。因此按照科班的表达式计算实验,给出了代码实现,逻辑还是很容易懂的。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务