实现一个计算数学表达示的功能
后缀表达式,如1+(3+1)*(3-2)后缀表达式是131+32-*+
解决表达式求值首先需要根据字符串表达式求出后缀表达式,然后使用后缀表达式和操作数栈实现计算,
计算的大致思想是从后缀表达式中取元素,如果元素是数值则加入到操作数栈中,
如果是运算符则从操作数栈中取两个数来参与运算。后缀表达式的获取要借助于两个栈,
一个是后缀表达式栈,一个是操作符栈,顺序扫描算术表达式,
如果是数值则直接加入后缀表达式栈,
如果是运算符则使用当前运算符和运算符栈中的栈顶元素做比较,
如果当前运算符的优先级高则当前元素进入操作符栈,
如果当前元素优先级低,则操作符栈顶元素出栈加入到后缀表达式栈中,一直到当前元素优先级高于操作符栈顶元素优先级则当前元素入操作符栈,
目前只支持加减乘除和带小括号的运算。
后缀表达式的计算规则:
弹出后缀表达式,
如果遇到一个数字则压到数字栈,
如果遇到一个符号,则从数字栈弹出两个数字进行计算,计算完再压回数字栈
以下是代码实现
public class Calculator {
static String[] operators = new String[]{"-", "+", "*", "/", "(", ")"};
static Stack digitStack;
static Stack operatorStack;
public static void main(String[] args) throws Exception {
digitStack = new Stack(100);
operatorStack = new Stack(100);
String s = "1+(3+1)*(3-2)";
transExpression(s);
System.out.println(calculate());
}
private static String calculate() throws Exception {
Stack stack = reverse(digitStack);
Stack stack1 = new Stack(100);
while (!stack.isEmpty()) {
String value = (String) stack.pop();
if (!isOperator(value)) {
stack1.push(value);
} else {
String value1 = (String) stack1.pop();
String value2 = (String) stack1.pop();
Double result = cal(value1, value2, value);
stack1.push(String.valueOf(result));
}
}
return (String) stack1.pop();
}
private static Stack reverse(Stack s) throws Exception {
Stack result = new Stack(s.length());
while (!s.isEmpty()) {
result.push(s.pop());
}
return result;
}
private static int getPriority(String operatorA) {
if (operatorA.equals("+") || operatorA.equals("-")) {
return 1;
} else if (operatorA.equals("*") || operatorA.equals("/")) {
return 2;
} else if (operatorA.equals("(") || operatorA.equals(")")) {
return 0;
}
return 0;
}
private static boolean isOperator(String a) {
for (String c : operators) {
if (c.equals(a)) {
return true;
}
}
return false;
}
private static boolean comparePriority(String operatorA, String operatorB) {
return getPriority(operatorA) >= getPriority(operatorB);
}
private static Double cal(String a, String b, String operator) {
Double tempValue1 = Double.parseDouble(a.toString());
Double tempValue2 = Double.parseDouble(b.toString());
if (operator.equals("+")) {
return tempValue1 + tempValue2;
}
if (operator.equals("-")) {
return tempValue2 - tempValue1;
}
if (operator.equals("*")) {
return tempValue1 * tempValue2;
}
if (operator.equals("/")) {
return tempValue2 / tempValue1;
}
return 0D;
}
private static String transExpression(String expression) throws Exception {
for (int i = 0; i < expression.length(); i++) {
String c = String.valueOf(expression.charAt(i));
if (isOperator(c)) {
if (operatorStack.isEmpty()) {
operatorStack.push(c);
} else {
//遇到一个右括号,则弹出操作栈到后缀栈,直到弹出的符号是左括号
if (c.equals(")")) {
String operator = (String) operatorStack.pop();
while (operator != null && !operator.equals("(")) {
digitStack.push(operator);
if (operatorStack.isEmpty()) break;
operator = (String) operatorStack.pop();
}
} else if (c.equals("(")) {
operatorStack.push(c);
} else {
String operator = (String) operatorStack.peek();
while (operator != null) {
//比如当前操作符优先级是否大于操作栈中栈顶的符号,如果大于,则压入操作栈,如果小于,则弹出操作栈的符号,
// 一直到弹出的操作符号小于当前符号为止
if (comparePriority(c, operator)) {
operatorStack.push(c);
break;
} else {
operator = (String) operatorStack.pop();
digitStack.push(operator);
operator = (String) operatorStack.peek();
if (operator == null) {
operatorStack.push(c);
break;
}
}
}
}
}
} else {
digitStack.push(c);
}
}
//将操作栈的符号压入到数字栈
while (!operatorStack.isEmpty()) {
digitStack.push(operatorStack.pop());
}
digitStack.display();
return "";
}
}