java实现堆栈的表达式求值(仅限于个位数)

这里栈用的是链式存储,首先将输入的前缀表达式转换为后缀表达式,然后求值。本来还想实现多位数和括号的表达式求值,但是写了一个多小时,总是报错,就先实现简单的吧。


  • 堆栈的链式结构存储实现:
//节点的代码
public class Node {
    public int data;
    public Node next;   //指向下一个节点

    public Node() {
    }

    public Node(int value) {
        this.data = value;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "num=" + data +
                '}';
    }
}

//实现链栈的代码
public class LinkedStack {
    //栈顶指针top
    Node top;
    //创建一个栈,栈顶指针top初始化为链表的头节点
    public LinkedStack() {
        top = new Node();
    }

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

    //入栈操作
    public void push(int value) {
        //申请一个新的节点
        Node temp = new Node();
        //将要插入的数据放入新的节点的data域中
        temp.data = value;
        //执行节点的插入操作
        temp.next = top.next;
        top.next = temp;
    }

    //出栈操作
    public int pop() {
        //定义一个临时变量,用来指向栈顶的第一个节点,即:top指针的下一个指针
        Node temp = top.next;
        if (isEmpty()) {
            throw new RuntimeException("栈空,不能出栈!");
        }
        top.next = temp.next;
        return temp.data;
    }

    //遍历并显示链栈中的元素
    public void showStack() {
        //定义一个临时变量,用来指向栈顶的节点,即:top指针的下一个指针
        Node temp = top.next;
        if (isEmpty()) {
            System.out.println("链栈为空!");
            return;
        }
        while (temp != null) {
            System.out.println(temp.data);
            temp = temp.next;
        }
    }

    //获取栈顶的元素但是不出栈
    public int getTop() {
        if (!isEmpty()) {
            return top.next.data;
        }else {
            return 0;
        }
    }
}

  • 具体表达式求值代码:
public static void main(String[] args) {
        //用来存放数据的栈
        LinkedStack valueStack = new LinkedStack();

        //用来存放操作符的栈
        LinkedStack symStack = new LinkedStack();

        //用来遍历表达式的索引变量
        int index=0;

        //是否扫描完了字符串的标志
        boolean sign = false;

        //从键盘输入表达式
        Scanner sc = new Scanner(System.in);

        //接收从键盘输入的表达式字符串
        String str = sc.next();

        //将字符串表达式中的数据和运算符存入数组中,方便遍历
        char[] array = str.toCharArray();

        //开始遍历字符串表达式
        while (true) {
            //还没遍历完表达式
            if (index < array.length) {
                //判断是否是数字
                if (!judge(array[index])) {
                    //是数字就直接入栈
                    valueStack.push(array[index]-'0');
                }else if (judge(array[index])) { //判断是否为运算符
                    //判断存放运算符的栈是否为空
                    if(symStack.isEmpty()) {
                        //如果为空,则直接将运算符入栈
                        symStack.push(array[index]);
                    }else {
                        //获取到符号栈中栈顶的运算符
                        int temp;
                        temp = symStack.top.next.data;
                        //如果不为空,则比较运算符的优先级
                        if (priority(array[index]) > priority(temp)) {
                            //如果当前运算符的优先级大于栈中运算符的优先级,直接入栈
                            symStack.push(array[index]);
                        }else {
                            while (priority(array[index]) <= priority(symStack.getTop())) {
                                if (!symStack.isEmpty()) {
                                    //如果当前运算符的优先级小于栈顶运算符的优先级时,将符号栈中的栈顶运算符出栈,直到当前运算符的优先级大于栈顶运算符的优先级为止
                                    //用一个临时变量存储计算的结果
                                    int result;
                                    //数字栈中出栈2个元素用符号栈中出栈的符号进行运算
                                    result = calc(valueStack.pop(), valueStack.pop(), symStack.pop());
                                    //在将计算的结果存入数字栈中,以用于下次的运算
                                    valueStack.push(result);
                                }else {
                                    break;
                                }
                            }
                            //如果当前运算符的优先级大于栈顶运算符的优先级时,将当前运算符入栈
                            symStack.push(array[index]);
                        }
                    }
                }
                index++;
            }else {
                //已经遍历完了表达式
                sign = true;
                break;
            }
        }
//        //遍历完字符串表达式
            //顺序将数字栈和符号栈中出栈相应的数和符号
            while (true) {
                if (valueStack.top.next.next == null) {
                    break;
                }
                //如果数字栈中只剩一个元素了,那它就是表达式的结果,最后直接出栈即可
                //用一个临时变量存储计算的结果
                int res;

                //数字栈中出栈2个元素用符号栈中出栈的符号进行运算
                res = calc(valueStack.pop(), valueStack.pop(), symStack.pop());

                //在将计算的结果存入数字栈中,以用于下次的运算
                valueStack.push(res);
            }
        //将表达式的结果显示出来
        valueStack.showStack();
    }

    //判断是不是运算符
    public static boolean judge(int value) {
        boolean sign;
        if (value == '*' || value == '/' || value == '+' || value == '-') {
            sign = true;
        }else {
            sign = false;
        }
        return sign;
    }

    //定义一个判断运算符优先级的方法
    //用返回值的大小来定义优先级
    public static int priority(int sym) {
        int result;
        if(sym == '*'  || sym == '/') {
            result = 1;
        }else if(sym == '+' || sym == '-') {
            result = 0;
        }else {
            result = -1;
        }
        return result;
    }

    //定义一个计算的方法
    public static int calc(int a,int b ,int sym) throws ArithmeticException {
        //用于存放计算的结果
        int r = 0;
        switch (sym) {
            case '*':
                r = a * b;
                break;
            case '/':
                r = b/a;
                break;
            case '+':
                r = a + b;
                break;
            case '-':
                r = b-a;
                break;
            default:
                break;
        }
        return r;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值