import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
/*
基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符。
即定义两个栈:operandStack(用来存放操作数)、operatorStack(用于存放操作符)。
在处理操作数和操作符之前,首先将它们压入栈中。当要处理一个操作符时,从operatorStack中将它弹出,
然后将它应用在来自operandStack的前两个操作数上,得到的结果再压入operandStack中.
实现的详细步骤:
1.扫描阶段:程序从左到右扫描表达式,提取操作数、运算符和括号。
1.1.如果提取的字符是一个操作数,将它压入operandStack中。
1.2.如果提取的字符是一个+或-的运算符,因为+、-运算符在算术表达式中的优先级是
最低的,所以此时在将+或者-运算符插入栈中之前,可以处理operatorStack栈顶的
所有运算符,最后将提取出来的运算符压入operatorStack中。
1.3.如果提取的字符是一个*或/的运算符,则处理operatorStack栈顶的所有*和/的运算
符,最后将新提取出来的运算符压入operatorStack中。
1.4.如果提取出来的运算符是一个"(",则将它压入operatorStack中。
1.5.如果提取出来的运算符是一个")",则重复处理operatorStack栈顶的运算符,直到看到栈顶的运算符为")"。
2.清除栈阶段:重复处理来自operatorStack栈顶的运算符,直到operatorStack为空为止。
*/
class Demo {
public static int evaluateExpression(String expression) {
Stack<Integer> operandStack = new Stack<Integer>();// 存放操作数的栈
Stack<Character> operatorStack = new Stack<Character>();// 存放运算符的栈
// 分割算术表达式
ArrayList<String> result = new ArrayList<String>();
String num = "";
for (int i = 0; i < expression.length(); i++) {
if (Character.isDigit(expression.charAt(i))) {
num = num + expression.charAt(i);
} else {
result.add(num);
result.add(expression.charAt(i) + "");
num = "";
}
}
result.add(num);
// 测试分割后的算术表达式
// for(String str:result){
// System.out.print(str+" ");
// }
// 后缀表达式
for (int i = 0; i < result.size(); i++) {
if (result.get(i).equals("+") || result.get(i).equals("-")) {
// 如果字符串为"+"或者"-",则执行栈中已存数据的加减乘除计算
while (!operatorStack.isEmpty() && (operatorStack.peek() == '+' || operatorStack.peek() == '-'
|| operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
processOneOperator(operandStack, operatorStack);
}
operatorStack.push(result.get(i).charAt(0));// 将操作符压入操作符栈中
} else if (result.get(i).equals("*") || result.get(i).equals("/")) {
// 如果字符串为"*"或者"/",则执行栈中已存数据的乘除计算
while (!operatorStack.isEmpty() && (operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
processOneOperator(operandStack, operatorStack);
}
operatorStack.push(result.get(i).charAt(0));
} else if (result.get(i).equals("(")) {
// 如果遇到左括号,则将左括号压入操作符栈中
operatorStack.push('(');
} else if (result.get(i).equals(")")) {
// 如果遇到右括号,则计算栈中的数据,直到遇到左括号为止
while (operatorStack.peek() != '(') {
processOneOperator(operandStack, operatorStack);
}
operatorStack.pop();// 将进行过计算的左括号弹出
} else {
// 如果遇到的是操作数,则将操作数直接压入操作数栈中
operandStack.push(Integer.parseInt(result.get(i)));
}
}
// 对栈中数据进行计算,知道栈为空为止
while (!operatorStack.isEmpty()) {
processOneOperator(operandStack, operatorStack);
}
// 此时操作数栈中的栈顶元素也就是计算结果
return operandStack.pop();
}
/**
* 对操作符栈顶的一个操作符进行计算
*
* @param operandStack
* @param operatorStack
*/
public static void processOneOperator(Stack<Integer> operandStack, Stack<Character> operatorStack) {
char op = operatorStack.pop();
// 取操作符的栈顶元素
int op1 = operandStack.pop();
// 取操作数的栈顶元素
int op2 = operandStack.pop();
// 取操作数的栈顶元素
if (op == '+') {
// 如果操作数为+,则执行两个操作数的求和操作,并将结果压入操作数栈中
operandStack.push(op2 + op1);
} else if (op == '-') {
operandStack.push(op2 - op1);
} else if (op == '*') {
operandStack.push(op2 * op1);
} else if (op == '/') {
operandStack.push(op2 / op1);
}
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
System.out.println("输入算术表达式(不支持浮点和负数的计算):");
while (cin.hasNext()) {
String s = cin.next();
// System.out.println("分割后的字符为:");
System.out.println(s + "=" + evaluateExpression(s));
}
cin.close();
}
}
(java)算术表达式的计算之后缀表达式
最新推荐文章于 2022-12-31 00:08:04 发布