题目: 使用栈来对表达式进行求值。对具有多个操作符和括号的复合表达式进行求值,假设操作数都是整数,运算符只包括+、-、×、/四种。
时间:2019.04.05
代码:
import java.util.Stack;
public class EvaluateExpression {
public static void main(String []args){
if(args.length!=1){
System.out.println("Usage: java EvaluateExpression \"expression\"");
System.exit(1);
}
//args[0]就是用命令行运行java程序时传入的第一个参数
try{
System.out.println(evaluateExpression(args[0]));
}catch(Exception e){
System.out.println("Wrong expression: "+args[0]);
}
}
public static int evaluateExpression(String expression){
Stack<Integer> operandStack=new Stack<>();
Stack<Character>operatorStack=new Stack<>();
expression=insertBlanks(expression);
String []tokens=expression.split(" ");
for(String token:tokens){
if(token.length()==0)
continue;
else if(token.charAt(0)=='+'||token.charAt(0)=='-'){
while(!operatorStack.isEmpty()&&(operatorStack.peek()=='+'||operatorStack.peek()=='-'
||operatorStack.peek()=='*'||operatorStack.peek()=='/'))
processAnOperator(operandStack,operatorStack);
operatorStack.push(token.charAt(0));
}
else if(token.charAt(0)=='*'||token.charAt(0)=='/'){
while(!operatorStack.isEmpty()&&(operatorStack.peek()=='*'||operatorStack.peek()=='/'))
processAnOperator(operandStack,operatorStack);
operatorStack.push(token.charAt(0));
}
//trim()去掉两端多余的空格
else if(token.trim().charAt(0)=='('){
operatorStack.push('(');
}
else if(token.trim().charAt(0)==')'){
while (operatorStack.peek()!='(')
processAnOperator(operandStack,operatorStack);
operatorStack.pop();
}
else
operandStack.push(new Integer(token));
}
while(!operatorStack.isEmpty()){
processAnOperator(operandStack,operatorStack);
}
return operandStack.pop();
}
public static void processAnOperator(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 String insertBlanks(String s){
String result="";
for (int i=0;i<s.length();i++){
if(s.charAt(i)=='('||s.charAt(i)==')'||s.charAt(i)=='+'||s.charAt(i)=='-'
||s.charAt(i)=='*'||s.charAt(i)=='/')
result+=" "+s.charAt(i)+" ";//用空格分隔开
else
result+=s.charAt(i);
}
return result;
}
}
该问题使用两个栈来解决问题,命名为operandStack和operatorStack,分别用于存放操作数和操作符。操作数和操作符在被处理前被压入栈中。当一个操作符被处理时,它从operatorStack中弹出,并应用于operandStaack中的前两个操作数,结果被压回operandStack中。