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

求Java实现SRPN(饱和逆波兰表示法)计算器的完整代码示例

SRPN计算器Java实现(饱和逆波兰表示法)

以下是完整的SRPN计算器实现,包含栈运算、要求的所有运算符、溢出饱和处理以及f历史调用功能:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class SRPNCalculator {
    private final Deque<Integer> operandStack = new ArrayDeque<>();
    private final List<Integer> historyNumbers = new LinkedList<>();
    private static final int MIN_INT = Integer.MIN_VALUE;
    private static final int MAX_INT = Integer.MAX_VALUE;

    public static void main(String[] args) {
        SRPNCalculator calculator = new SRPNCalculator();
        calculator.start();
    }

    public void start() {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
            String input;
            System.out.println("SRPN计算器已启动,输入数字/运算符/指令,输入'exit'退出");
            while ((input = reader.readLine()) != null) {
                input = input.trim();
                if (input.isEmpty()) continue;
                if ("exit".equalsIgnoreCase(input)) break;
                processInput(input);
            }
        } catch (IOException e) {
            System.err.println("输入读取错误: " + e.getMessage());
        }
    }

    private void processInput(String input) {
        // 按空格拆分输入,支持多token一行输入
        String[] tokens = input.split("\\s+");
        for (String token : tokens) {
            if (token.matches("-?\\d+")) {
                // 处理数字
                int num = Integer.parseInt(token);
                operandStack.push(num);
                historyNumbers.add(num);
            } else if (token.equals("=")) {
                // 输出栈顶元素
                if (!operandStack.isEmpty()) {
                    System.out.println(operandStack.peek());
                } else {
                    System.err.println("错误:栈为空,无法输出");
                }
            } else if (token.startsWith("f")) {
                // 处理f指令,格式如f1、f3
                if (token.length() < 2) {
                    System.err.println("错误:f指令格式错误,需后跟数字,如f1");
                    continue;
                }
                String indexStr = token.substring(1);
                if (!indexStr.matches("\\d+")) {
                    System.err.println("错误:f指令后的参数必须是正整数");
                    continue;
                }
                int index = Integer.parseInt(indexStr) - 1; // 转0索引
                if (index < 0 || index >= historyNumbers.size()) {
                    System.err.println("错误:历史数字索引超出范围");
                    continue;
                }
                int num = historyNumbers.get(index);
                operandStack.push(num);
            } else {
                // 处理运算符
                processOperator(token);
            }
        }
    }

    private void processOperator(String operator) {
        if (operandStack.size() < 2) {
            System.err.println("错误:栈中元素不足,无法执行" + operator + "运算");
            return;
        }
        int b = operandStack.pop();
        int a = operandStack.pop();
        int result = 0;
        boolean overflow = false;

        switch (operator) {
            case "+":
                result = a + b;
                // 检查加法溢出
                overflow = (b > 0 && a > MAX_INT - b) || (b < 0 && a < MIN_INT - b);
                break;
            case "-":
                result = a - b;
                // 检查减法溢出
                overflow = (b < 0 && a > MAX_INT + b) || (b > 0 && a < MIN_INT + b);
                break;
            case "*":
                result = a * b;
                // 检查乘法溢出
                overflow = (a != 0 && b != 0 && (result / a != b));
                break;
            case "%":
                if (b == 0) {
                    System.err.println("错误:模运算除数不能为0");
                    operandStack.push(a);
                    operandStack.push(b);
                    return;
                }
                result = a % b;
                // 处理负数模运算的一致性,保证结果符号与被除数一致
                if ((a < 0 && b > 0) || (a > 0 && b < 0)) {
                    result += b;
                }
                break;
            case "^":
                // 幂运算,只处理整数幂,底数为负时指数需为正整数
                if (b < 0) {
                    System.err.println("错误:幂运算指数不能为负数");
                    operandStack.push(a);
                    operandStack.push(b);
                    return;
                }
                if (a == 0 && b == 0) {
                    System.err.println("错误:0的0次方无意义");
                    operandStack.push(a);
                    operandStack.push(b);
                    return;
                }
                result = 1;
                for (int i = 0; i < b; i++) {
                    // 每一步检查溢出
                    if (result > MAX_INT / a || result < MIN_INT / a) {
                        overflow = true;
                        break;
                    }
                    result *= a;
                }
                break;
            default:
                System.err.println("错误:不支持的运算符" + operator);
                operandStack.push(a);
                operandStack.push(b);
                return;
        }

        // 饱和处理:溢出时设置为最大/最小值
        if (overflow) {
            result = (operator.equals("+") || operator.equals("*") || (operator.equals("^") && b > 0)) ? MAX_INT : MIN_INT;
        }
        operandStack.push(result);
        historyNumbers.add(result);
    }
}

关键功能说明

  • 栈运算逻辑:使用Deque<Integer>实现栈结构,完全适配逆波兰表达式后进先出的运算规则
  • 溢出饱和处理:对加减乘幂运算做溢出检查,溢出时自动将结果截断到Integer.MAX_VALUE或Integer.MIN_VALUE
  • f指令实现:用List<Integer>记录所有输入过的有效数字(包括运算结果),输入fN时调用第N个历史数字(N从1开始计数)
  • 多输入支持:支持单token单行或多token单行输入(比如输入3 3 * =可直接输出9)
  • 异常场景处理:覆盖了除数为0、0的0次方、栈元素不足、无效指令等异常情况

使用示例

  1. 基础运算:输入3 3 * =,输出9
  2. 多步运算:输入3 3 * 4 4 * + =,输出25
  3. f指令调用:先输入5 7,再输入f1 f2 * =,输出35

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:55:21