1 将中缀表达式转换成后缀表达式
2 计算后缀表达式的值
后缀表达式的求值就容易多了
按顺序将操作数入栈, 遇到操作符时,从栈中提出两个操作数,用操作符将其执行运算,将结果入栈
import java.util.Stack;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Map;
import java.util.HashMap;
public class ArithmeticExpressionEvaluation {
private static Stack<Character> theStack;
private static char charKey=(char)97;
private static Map<Character,String> hashMap=new HashMap<Character,String>();
private static String result;
public static void main(String[] args) {
if(args.length<1) {
System.out.println(" please enter the input arithmetic expression string that needs to be evaluated."+
"the legal operators include '+', '-','*' and '/' ,and you can also add '(' and ')' ."+
"all numbers must above zero, the program doesn't support negative values now "
);
System.exit(0);
}
System.out.println("the original input is :"+args[0]);
String internalStr=processBeforeEvaluation(args[0]);
System.out.println("the internal expression is :"+internalStr);
String postfixStr= translateToPostfixExpression(internalStr);
System.out.println("the postfix expression is :"+postfixStr);
double result=evaluatePostfixExpression(postfixStr);
System.out.println("the final result is :"+result);
}
private static String processBeforeEvaluation(String input) {
Matcher legal=Pattern.compile("[^0-9.*+/\\()-]").matcher(input);
if(legal.find()) {
System.out.println("Please enter legal arithmetic expression string.");
System.exit(0);
}
StringBuffer sbuf = new StringBuffer();
Matcher m=Pattern.compile("\\d+(\\.\\d+)?").matcher(input);
while(m.find()) {
String temp=m.group(0);
hashMap.put(charKey,temp);
m.appendReplacement(sbuf,charKey+"");
charKey=(char)(charKey+1);
}
m.appendTail(sbuf);
return sbuf.toString();
}
private static String translateToPostfixExpression(String input) {
theStack=new Stack<Character>();
result="";
for(int j=0; j<input.length(); j++) {
char ch=input.charAt(j);
switch(ch) {
case '+':
case '-':
case '*':
case '/':
gotOper(ch);
break;
case '(':
theStack.push(ch);
break;
case ')':
gotParen(ch);
break;
default :
result+=ch;
break;
} //end switch
} //end for loop
while(!theStack.empty()) {
result+=theStack.pop();
}
return result;
}
private static void gotOper(char opThis) {
while(!theStack.empty()) {
char opTop=theStack.pop();
if(opTop=='(') {
theStack.push(opTop);
break;
} else {
if(opThis=='*'||opThis=='/') { //如果是本次是乘除,栈里最多可弹出一个乘号
if(opTop=='+'||opTop=='-') {
theStack.push(opTop);
} else {
result+=opTop;
}
break;
} else { //如果是本次是加减,栈里最多可弹出一次乘除,再加一次加减
result+=opTop;
}
} //end else
}//end while
theStack.push(opThis);
}//end gotOper()
private static void gotParen(char ch) {
while(!theStack.empty()) {
char chx=theStack.pop();
if(chx=='(')
break;
else
result+=chx;
} //end while
}
private static double evaluatePostfixExpression(String input) {
System.out.println("the content of the hashMap is :"+hashMap);
char ch;
double num1,num2,interAns=0;
String str1,str2;
theStack=new Stack<Character>(); //重置栈,后缀表达式求值是将数字放入栈中
try {
for(int j=0; j<input.length(); j++) {
ch=input.charAt(j);
if(ch>=97) { //j代表一个double型的数字
theStack.push(ch);
} else {
str2 =hashMap.get(theStack.pop());
str1=hashMap.get(theStack.pop());
num2=Double.parseDouble(str2);
num1=Double.parseDouble(str1);
switch(ch) {
case '+':
interAns=num1+num2;
break;
case '-':
interAns=num1-num2;
break;
case '*':
interAns=num1*num2;
break;
case '/':
interAns=num1/num2;
break;
default :
interAns=0;
break;
} //end switch
hashMap.put(charKey,interAns+"");
theStack.push(charKey);
charKey=(char)(charKey+1);
} //end else
} //end for loop
str1=hashMap.get(theStack.pop());
interAns=Double.parseDouble(str1);
} catch(Exception e) {
System.out.println("please enter legal numbers!");
e.printStackTrace();
}
return interAns;
}
}