public class Evaluate {
public static double[] parseNum(char[]str,int i){
double num=0;
int k=-1;
for(;i<str.length;i++){
if(str[i]>='0'&&str[i]<='9'){
num=num*10+str[i]-'0';
if(k!=-1)
k++;
}
else if(str[i]=='.')
k++;
else
break;
}
while (k>0){
num/=10;
k--;
}
double[] ret=new double[2];
ret[0]=num;
ret[1]=i;
return ret;
}
/*
后缀表达式求值。
遇到数值就放到栈中,遇到操作符,就从栈顶取出操作数,运算后结果放回栈中。
*/
public static double postEvaluate(char[] strs){
LinkedList<Double>numStack=new LinkedList<>();
for(int i=0;i<strs.length&&strs[i]!='#';i++){
if(strs[i]>='0'&&strs[i]<='9'){
double []ret=parseNum(strs,i);
numStack.push(ret[0]);
i=(int)ret[1]-1;
}else if(strs[i]=='*'){
double n2=numStack.pop();
double n1=numStack.pop();
numStack.push(n1*n2);
}else if(strs[i]=='/'){
double n2=numStack.pop();
double n1=numStack.pop();
numStack.push(n1/n2);
}else if(strs[i]=='+'){
double n2=numStack.pop();
double n1=numStack.pop();
numStack.push(n1+n2);
}else if(strs[i]=='-'){
double n2=numStack.pop();
double n1=numStack.pop();
numStack.push(n1-n2);
}else if(strs[i]=='.')
continue;
}
return numStack.pop();
}
public static int priority(char c){
switch (c){
case '#':
case '(':return -1;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return -1;
}
}
public static boolean isOp(char c){
switch (c){
case '+':
case '-':
case '*':
case '/':
return true;
default:
return false;
}
}
/*
将中缀表达式的符号插入到操作数的适当位置,就可以用后缀表达式求值了。
如果遇到左括号,说明一个新的表达式开始,将 左括号入栈
如果遇到又括号,说明一个表达式结束,将栈中元素一直退栈放到后缀表达式,直到遇到第一个左括号,然后将左括号也退栈
如果遇到操作符,那么将栈顶优先级大于等于它的操作符全部退栈放到后缀表达式,直到栈顶优先级比它小,那么把该操作符加入
思想: 后缀表达式与中缀表达式操作数顺序相同,不同的就是操作符顺序, 只要根据优先级安排操作符位置就好。
遇到数,就直接放进去。
遇到操作符,因为不确定后面的操作符的优先级是不是比它高,所以先放到栈中保存,同时,如果栈顶那些操作符优先级大于等于它的话,
可以确定那些操作符可以先进行运算,所以把栈顶比它优先级大和相等的全部退栈,直到遇到比它优先级小的。
*/
public static double mieEvaluate(char strs[]){
char[] pstrs=new char[strs.length*2];
LinkedList<Character>opStack=new LinkedList<>();
int i=0,j=0;
for(;i<strs.length;i++){
if(strs[i]>='0'&&strs[i]<='9'||strs[i]=='.')
pstrs[j++]=strs[i];
else if(strs[i]=='(')
opStack.push('(');
else if(strs[i]==')'){
while (opStack.peek()!='(')
pstrs[j++]=opStack.pop();
opStack.pop();
}else if(isOp(strs[i])){
pstrs[j++]=' ';
while (!opStack.isEmpty()&&priority(opStack.peek())>=priority(strs[i]))
pstrs[j++]=opStack.pop();
opStack.push(strs[i]);
}
}
while (!opStack.isEmpty())
pstrs[j++]=opStack.pop();
pstrs[j++]='#';
return postEvaluate(pstrs);
}
public static void main(String []args){
Scanner scanner=new Scanner(System.in);
while (scanner.hasNext()){
String line=scanner.nextLine();
System.out.println(mieEvaluate(line.toCharArray()));
}
}
}
后缀表达式与中缀表达式求值
猜你喜欢
转载自blog.csdn.net/yzr1183739890/article/details/68951982
今日推荐
周排行