思路
先把表达式转为后缀表达式,再计算后缀表达式的结果
中缀转为后缀表达式可以去括号,方便计算
代码
package myPackage;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
public class Main {
//检查数字的长度
static public int findNumLen(String expression, int startIndex) {
for (int index = startIndex, len = expression.length(); index < len; index++) {
if (expression.charAt(index) >= '0' && expression.charAt(index) <= '9')
startIndex++;
else
break;
}
return startIndex;
}
//把每个数字符号分为单独的String放在Li
static public List<String> transformList(String expression) {
List<String> list = new ArrayList<>();
char[] chars = expression.toCharArray();
int curIndex = 0;
//第一个数可能为负数,单独写出来
while (true) {
if (chars[curIndex] >= '0' && chars[curIndex] <= '9' || chars[curIndex] == '-')
curIndex++;
else
break;
}
list.add(expression.substring(0, curIndex)); //把第一个数添加进来
int index = curIndex;
while (index < chars.length) {
if (chars[index] == '+' || chars[index] == '-' || chars[index] == '*' || chars[index] == '/' || chars[index] == '(' || chars[index] == ')') {
list.add("" + chars[index]);
index++;
} else {
int end = findNumLen(expression, index); //获取数字的结束下标的 下一个
list.add(expression.substring(index, end)); //添加提取出来的数字到集合
index = end; //等于上一个数的结束下标的下一个
}
}
return list;
}
//符合是否符合出栈条件,符合返回true,否则返回false,"*与/" 的优先级大于 "+与-"
static public boolean judgePop(String a, String b) {
if (a.equals("+") || a.equals("-")) {
if (b.equals("*") || b.equals("/")) {
return true;
}
}
if (a.equals("*") || a.equals("/")) {
if (b.equals("+") || b.equals("-")) {
return false;
}
}
return false;
}
static public List<String> transformSuffix(String expression) {
List<String> list = transformList(expression);
List<String> result = new ArrayList<>();
Stack<String> operator = new Stack<>(); //用于存储运算符的栈
for (String a : list) {
//如果最后以为是数字,那么这个数就是数字
if (a.charAt(a.length() - 1) >= '0' && a.charAt(a.length() - 1) <= '9') {
result.add(a);
} else if (a.equals("+") || a.equals("-") || a.equals("*") || a.equals("/") || a.equals("(")) {
if (operator.size() >= 1 && judgePop(a, operator.peek())) { //如果符合出栈天剑
//如果要添加的符号优先级比栈顶的符号优先级高,则先把栈中所有的符号取出添加到结果列表中,再把新的符号添加到栈中
while (!operator.isEmpty()) { //把所有符号出栈并把符号添加到结果中
result.add(operator.pop());
}
operator.add(a); //添加新的符号
} else {
operator.add(a); //添加新的符号
}
} else { //遇到右括号时,把对应左括号之间的运算符号输出,遇到左括号时停止
while (!operator.peek().equals("(")) {
result.add(operator.pop());
}
operator.pop(); //左括号出栈
}
}
while (!operator.isEmpty()) { //把所有符号出栈
result.add(operator.pop());
}
return result;
}
static public double calculate(List<String> list) {
Stack<Double> tempStack = new Stack<>(); //用于临时存储
for (String s : list) {
if (s.charAt(s.length() - 1) >= '0' && s.charAt(s.length() - 1) <= '9') {
tempStack.push(Double.parseDouble(s));
} else {
double a = tempStack.pop();
double b = tempStack.pop();
double t = 0; //存储临时结果
switch (s) {
case "+":
t = b + a;
break;
case "-":
t = b - a;
break;
case "*":
t = b * a;
break;
case "/":
t = b / a;
break;
}
tempStack.push(t);
}
}
double run = 0;
for (Double d : tempStack) {
run += d;
}
return run;
}
public static void main(String[] args) {
System.out.print("请输入表达式:");
String expression = new Scanner(System.in).nextLine().replaceAll(" ", ""); //去除所有空格
for (String s : transformSuffix(expression)) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("结果为:" + calculate(transformSuffix(expression)));
}
}
结果
9+(3-1)*3+10/2