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

基于链表实现栈:如何读取后缀表达式文件并填充栈?

没问题,我来帮你搞定用链表栈处理后缀表达式文件的事儿!下面一步步给你讲清楚怎么实现:

用链表栈处理后缀表达式文件的完整实现指南

一、先确认你的GenericStack类具备必要方法

你已经定义了GenericStack和Node类,但要确保它有栈的核心操作:push、pop、isEmpty。如果还没完全实现,这里补全一下:

public class GenericStack<T> {
    private Node<T> top;

    public GenericStack() {
        top = null;
    }

    // 压栈:把元素放到栈顶
    public void push(T data) {
        Node<T> newNode = new Node<>(data);
        newNode.next = top;
        top = newNode;
    }

    // 弹栈:取出栈顶元素并移除,栈空时抛出异常
    public T pop() {
        if (isEmpty()) {
            throw new IllegalStateException("栈为空,无法弹出元素");
        }
        T data = top.data;
        top = top.next;
        return data;
    }

    // 判断栈是否为空
    public boolean isEmpty() {
        return top == null;
    }

    // 内部Node类,用于构建链表
    private static class Node<T> {
        T data;
        Node<T> next;

        Node(T data) {
            this.data = data;
            this.next = null;
        }
    }
}

二、在Evaluator类中实现文件读取与栈处理逻辑

接下来,在你的Evaluator类的main方法里,我们要完成读取文件→分割表达式→处理栈计算的完整流程:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class Evaluator {
    public static void main(String[] args) {
        // 这里替换成你的输入文件路径,也可以通过命令行参数传入args[0]更灵活
        String filePath = "postfix_expressions.txt";
        // 因为后缀表达式计算常用整数,这里泛型指定为Integer,需要浮点数就改成Double
        GenericStack<Integer> stack = new GenericStack<>();

        try {
            // 读取文件所有行,每行对应一个后缀表达式
            List<String> lines = Files.readAllLines(Paths.get(filePath));
            for (String line : lines) {
                // 把每行按空格分割成单个token(数字或运算符),支持多空格分隔
                String[] tokens = line.trim().split("\\s+");
                for (String token : tokens) {
                    if (isNumeric(token)) {
                        // 是数字就转成Integer压入栈
                        stack.push(Integer.parseInt(token));
                    } else {
                        // 是运算符就弹出两个操作数计算,注意操作数顺序
                        if (stack.isEmpty()) {
                            throw new IllegalArgumentException("无效表达式:运算符缺少操作数");
                        }
                        int operand2 = stack.pop(); // 后弹出的是第二个操作数
                        if (stack.isEmpty()) {
                            throw new IllegalArgumentException("无效表达式:运算符缺少操作数");
                        }
                        int operand1 = stack.pop(); // 先弹出的是第一个操作数
                        // 计算结果并压回栈
                        int result = calculate(operand1, operand2, token);
                        stack.push(result);
                    }
                }
                // 处理完一行后,栈顶就是该表达式的结果
                if (!stack.isEmpty()) {
                    System.out.println("表达式 '" + line + "' 的结果:" + stack.pop());
                }
            }
        } catch (IOException e) {
            System.err.println("读取文件出错:" + e.getMessage());
        } catch (IllegalArgumentException | ArithmeticException | IllegalStateException e) {
            System.err.println("处理出错:" + e.getMessage());
        }
    }

    // 辅助方法:判断字符串是否是整数
    private static boolean isNumeric(String str) {
        try {
            Integer.parseInt(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    // 辅助方法:根据运算符计算结果
    private static int calculate(int operand1, int operand2, String operator) {
        return switch (operator) {
            case "+" -> operand1 + operand2;
            case "-" -> operand1 - operand2;
            case "*" -> operand1 * operand2;
            case "/" -> {
                if (operand2 == 0) {
                    throw new ArithmeticException("除数不能为0");
                }
                yield operand1 / operand2;
            }
            default -> throw new IllegalArgumentException("不支持的运算符:" + operator);
        };
    }
}

三、关键步骤说明

  • 文件读取:用Files.readAllLines可以快速读取小文件,如果你处理的是大文件,建议用BufferedReader逐行读取,避免内存占用过高。
  • Token分割:用\\s+作为分隔符,可以匹配多个空格,避免表达式中多个空格导致的空token问题。
  • 栈操作逻辑:后缀表达式的核心就是「遇数压栈,遇运算符弹栈计算」,这里要注意操作数的顺序:比如6 5 2 3 + 8 * + 3 + *这个表达式,遇到+时,要弹出3和2,计算2+3=5,再把5压栈,以此类推。
  • 异常处理:覆盖了文件读取失败、表达式格式错误、除数为0、栈空操作等常见异常,让程序更健壮。

四、测试一下

假设你的输入文件postfix_expressions.txt里有一行:

6 5 2 3 + 8 * + 3 + *

运行程序后,会输出:

表达式 '6 5 2 3 + 8 * + 3 + *' 的结果:288

这个结果是正确的,手动计算验证:((2+3)*8 +5 +3)*6 = (5*8+8)*6 = (40+8)*6=48*6=288。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:00:11