双栈算术表达式求值算法
栈
栈是一种基于先进后出策略(LIFO)的集合类型。
算术表达式
例如 ( 1 + ( 5 – 2 ) * ( 6 + 3 ) )
算法要求描述
要求输入算术表达式字符串,每个字符和数字之间用 空格(space) 间隔开, 程序输出 表达式的值。(简单起见,暂且仅实现 加减乘除,并且不省略括号 )
思路
- 首先我们需要两个栈:operator(用于存放操作符)、 number(用于存放操作数)
- 忽略左括号
- 遇到操作符,将其压入operator栈
- 遇到操作数,将其压入number栈
- 遇到右括号,弹出一个操作符,弹出两个操作数,根据操作符和操作数计算出结果,并且将其压入number栈
该算法看似比较繁琐,其实不然。每当遇到一个右括号时,这就意味着遇到了一个子表达式,由栈的先进后出特性,可以分析到:operator栈顶元素就是该子表达式的操作符,number栈中顶端两个元素就是该子表达式的两个操作数,这样,我们就可以将操作符和两个操作数弹出,计算出其结果,该结果就可以代替该子表达式,作为一个操作数压入number栈。直到最后一个右括号出现,最终number栈中只有一个元素,也就是我们想要的表达式的值。
代码实现
import java.util.Scanner;
import java.util.Stack;
public class MainClass {
public static double expressionCaculate(String str){
//存放操作符的栈
Stack<String> opr = new Stack<String>();
//存放操作数的栈
Stack<Double> number = new Stack<Double>();
String[] list = str.split(" ");
for (String s : list) {
if(s.equals("(")){
continue;
}else if(s.equals("+")){
opr.push(s);
}else if(s.equals("-")){
opr.push(s);
}else if(s.equals("*")){
opr.push(s);
}else if(s.equals("/")){
opr.push(s);
}else if(s.equals(")")){
String op = opr.pop();
double val = number.pop();
switch(op){
case "+":
val = number.pop() + val;
break;
case "-":
val = number.pop() - val;
break;
case "*":
val = number.pop() * val;
break;
case "/":
val = number.pop() / val;
break;
}
number.push(val);
}else{
number.push(Double.parseDouble(s));
}
}
return number.pop();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
System.out.println(str + " = " + expressionCaculate(str));
}
}
感谢阅读