后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行。
运用后缀表达式进行计算的具体做法:
建立一个操作数栈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;
}
}
}