You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中正确实现含关系、逻辑运算符的后缀表达式求值?

现有代码核心问题

  • isOperator判断逻辑不合理:仅通过首个字符是否为字母/数字判定是否为运算符,易误判特殊输入,建议改用运算符白名单校验
  • 逻辑运算符实现错误:&&、|| 目前使用按位与&、按位或|实现,和实际逻辑运算规则不符。逻辑运算仅需判断操作数是否非零,无需按位计算
  • ^运算符歧义:当前代码实现为按位异或,若业务中^表示幂运算,需改用Math.pow实现
  • 栈和队列未指定泛型:操作时需要反复强转类型,容易出现类型转换异常

修复后代码

import java.util.*;

public class PostEvaluator {
    // 运算符白名单,避免误判
    private static final Set<String> OPERATORS = new HashSet<>(Arrays.asList(
            "*", "/", "+", "-", "%", "^", ">", "<", ">=", "<=", "!=", "==", "&&", "||", "!"
    ));

    private Stack<String> stack;
    private Queue<String> queue;

    public PostEvaluator() {
        stack = new Stack<>();
        queue = new LinkedList<>();
    }

    private static boolean isOperator(String c) {
        return OPERATORS.contains(c);
    }

    private int operate(int x, int y, String operator) {
        switch (operator) {
            case "*":
                return x * y;
            case "/":
                if (y == 0) {
                    System.out.println("Division by zero error!");
                    System.exit(0);
                }
                return x / y;
            case "+":
                return x + y;
            case "-":
                return x - y;
            case "%":
                return x % y;
            case "^":
                // 若为幂运算请替换为下面的代码
                // return (int) Math.pow(x, y);
                // 当前保留按位异或逻辑
                return x ^ y;
            case ">":
                return x > y ? 1 : 0;
            case "<":
                return x < y ? 1 : 0;
            case ">=":
                return x >= y ? 1 : 0;
            case "<=":
                return x <= y ? 1 : 0;
            case "!=":
                return x != y ? 1 : 0;
            case "==":
                return x == y ? 1 : 0;
            case "&&":
                // 逻辑与:两个操作数都非零返回1,否则0
                return (x != 0 && y != 0) ? 1 : 0;
            case "||":
                // 逻辑或:任意一个操作数非零返回1,否则0
                return (x != 0 || y != 0) ? 1 : 0;
            default:
                System.out.println("Unknown operator: " + operator);
                System.exit(0);
                return 0;
        }
    }

    private int notOperate(int x) {
        return x == 0 ? 1 : 0;
    }

    public String evaluatePostFix(String input) {
        String val1, val2, result = "", temp;
        int intVal1, intVal2;
        Scanner kb = new Scanner(input);
        kb.useDelimiter(" ");

        while (kb.hasNext()) {
            // 若使用自定义Queue,请替换为你自己的enqueue方法
            queue.offer(kb.next());
        }

        while (!queue.isEmpty()) {
            // 若使用自定义Queue,请替换为你自己的dequeue方法
            temp = queue.poll();
            if (temp.isBlank()) continue;

            if (!isOperator(temp)) {
                stack.push(temp);
                if (result.equals("")) {
                    result = temp;
                }
            } else {
                if (stack.isEmpty()) {
                    System.out.println("Missing Operand/s Error");
                    System.exit(0);
                }
                if (!temp.equals("!")) {
                    val1 = stack.pop();
                    if (stack.isEmpty()) {
                        System.out.println("Missing Operand/s Error");
                        System.exit(0);
                    }
                    val2 = stack.pop();
                    intVal1 = Integer.parseInt(val1);
                    intVal2 = Integer.parseInt(val2);
                    result = Integer.toString(operate(intVal2, intVal1, temp));
                    stack.push(result);
                } else {
                    val1 = stack.pop();
                    intVal1 = Integer.parseInt(val1);
                    result = Integer.toString(notOperate(intVal1));
                    stack.push(result);
                }
            }
        }
        // 最后校验栈中是否只剩一个结果,否则说明表达式不合法
        if (stack.size() != 1) {
            System.out.println("Invalid expression error");
            System.exit(0);
        }
        return stack.pop();
    }
}

补充说明

后缀表达式求值的逻辑本身和运算符类型无关,只要保证运算符的运算逻辑正确、中缀转后缀时的运算符优先级和结合性处理正确即可,关系/逻辑运算符的求值规则和算术运算符一致,都是遇到运算符就弹出对应数量的操作数计算后将结果压回栈。如果你使用的是自定义的Stack和Queue实现,把代码中对应栈队列的操作换回你自己的方法即可。

内容的提问来源于stack exchange,提问作者Wreckzonee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 10:57:01