7-1 后缀表达式求值

后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行。

运用后缀表达式进行计算的具体做法:

建立一个操作数栈S。然后从左到右读表达式,如果读到操作数就将它压入栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项操作数进行运算,再将运算的结果代替原栈顶的n项压入栈中。重复上面过程,如果后缀表达式读完且栈中只剩一个操作数,则该数就是运算结果;如果后缀表达式读完但是栈中操作数多于一个,则后缀表达式错误;如果栈中操作数只剩一个,但是后缀表达式还未读完且当前运算符为双元操作符,则后缀表达式同样错误。

输入格式:
在一行中输入一个以#号结束的非空后缀式,#不属于表达式的一部分,操作数和运算符都以空格分隔,运算数为绝对值不超过100的整数,运算符仅有+、-、*、/ 四种。

输出格式:
输出后缀式计算结果,所有的计算都只取结果的整数部分。题目保证计算的中间和最后结果的绝对值都不超过10的9次方 。

如果执行除法时出现分母为零的非法操作,则在一行中输出:Error: X/0,X是当时的分子。

如果后缀表达式中运算符多了或者少了,则在一行中输出:Expression Error: X,X是当时栈顶元素。

输入样例1:
5 -2 + 3 * #
输出样例1:
9
输入样例2:
5 -2 2 + / #
输出样例2:
Error: 5/0
输入样例3:
5 -1 3 + / - * #
输出样例3:
Expression Error: 2
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String data = scanner.nextLine();
        calculate(data);
    }

    public static void calculate(String data) {
        Stack stack = new Stack();
        //按照空格进行拆分
        String[] s = data.split(" ");
        for (String str : s) {
            //判断是否是四则运算
            if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/") || str.equals("#")) {
                //如果遇到#结束循环
                if (str.equals("#")) {
                    //如果栈内元素不等于1说明运算符少了
                    if (stack.count != 1) {
                        System.out.print("Expression Error: " + stack.getData());
                        return;
                    }
                    break;
                }
                //如果栈内只有一个元素,还要运算,说明运算符多了
                if (stack.count == 1) {
                    System.out.print("Expression Error: " + stack.getData());
                    return;
                }
                //取出栈顶的前两元素
                int one = stack.getData();
                int two = stack.getData();
                //用于存储结果的变量
                int result = 0;
                switch (str) {
                    case "+":
                        result = two + one;
                        break;
                    case "-":
                        result = two - one;
                        break;
                    case "*":
                        result = two * one;
                        break;
                    case "/":
                        if (one == 0) {
                            System.out.print("Error: " + two + "/0");
                            //遇到除数是0直接退出
                            return;
                        }
                        result = two / one;
                        break;
                }
                //入栈
                stack.add(result);
            } else {
                //如果不是运算符,就直接入栈
                stack.add(Integer.parseInt(str));
            }
        }
        if (stack.count != 1) {
            System.out.print("Expression Error: " + stack.getData());
            return;
        }
        stack.printf();
    }
}

class Stack {
    private class Node { //外部不需要使用,所以作为私有类
        private final int data; //存储数据
        private Node next; //保存下一个节点

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

        public void addNode(Node newNode) {
            newNode.next = root;
            root = newNode;
        }
    }

    private Node root; //根节点
    int count;

    public void add(int data) {
        Node newNode = new Node(data); //创建新节点
        if (root == null) {
            this.root = newNode;
        } else {//应该交由Node类负责处理
            this.root.addNode(newNode);
        }
        count++;
    }

    public void clear() {
        if (root != null) {
            root = null;
        }
        count = 0;
    }

    public int getData() {
        Node temp = root;
        root = root.next;
        count--;
        return temp.data;
    }

    public void printf() {
        Node tempNode = root;
        while (tempNode != null) {
            System.out.print(tempNode.data);
            tempNode = tempNode.next;
        }
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值