import java.util.Collections;
import java.util.LinkedList;
public class ExpressionEvaluation {
/**
* 后缀表达式求值
* 尼玛,菜鸟写了半天
* @param args
*/
LinkedList<Character> operateStack = new LinkedList<Character>();//中间栈,转成后缀表达式借助的栈
LinkedList<Integer> result = new LinkedList<Integer>();// 结果栈
LinkedList<Character> opera = new LinkedList<Character>();// 运算符栈
LinkedList<String> suffixStack = new LinkedList<String>();// 后缀表达式栈,采用String存储,方便计算多位数
char[] symbol = { '+', '-', '*', '/', '^', '(', ')','#' };// 符号数组
int in[] = { 3, 3, 5, 5, 7, 1, 8,0};// 栈内元素优先级
int out[] = { 2, 2, 4, 4, 6, 8, 1,0 };// 栈外元素优先级
public static void main(String[] args) {
String expression="1^2*3-4+5/(16/(7+8))#";
ExpressionEvaluation ee=new ExpressionEvaluation();
System.out.println(ee.getSuffixExpression(expression));
System.out.println(ee.getValue(ee.getSuffixExpression(expression)));
}
//获取符号的下标
public int get(char c){
switch(c){
case '+':return 0;case '-':return 1;case '*':return 2;case '/':return 3;
case '^':return 4;case '(':return 5;case ')':return 6;case '#':return 7;default :return 7;
}
}
//判断是否是操作符
public boolean isOperator(char c){
return c=='+'||c=='-'||c=='*'||c=='/'||c=='^'||c=='('||c==')'||c=='#';
}
//计算后缀表达式,这里的返回值采用的是整型,实际采用浮点型是比较好的
public int getValue(LinkedList<String> suffixStack){
opera.push('#');
Collections.reverse(suffixStack);
for(int i=0;i<suffixStack.size();i++){
if(isOperator(suffixStack.peek().charAt(0))){
char top=opera.peek();
if(out[get(suffixStack.peek().charAt(0))]>in[get(top)]){
int one=result.pop();
int two=result.pop();
result.push(calculate(one,two,suffixStack.pop().charAt(0)));
}
}else{
result.push(Integer.parseInt(suffixStack.pop()));
}
}
/*这种方法不好的原因是只能运算操作数是10以内的表达式
* char[] suffix=suffixExpression.toCharArray();
for(int i=0;i<suffix.length;i++){
if(isOperator(suffix[i])){
System.out.println(opera.isEmpty());
char top=opera.peek();
if(out[get(suffix[i])]>in[get(top)]){
int one=result.pop();
int two=result.pop();
result.push(calculate(one,two,suffix[i]));
}
}else{
result.push(Integer.parseInt(String.valueOf(suffix[i])));
}
}*/
return result.pop();
}
//将中缀表达式转换成后缀表达式
public LinkedList<String> getSuffixExpression(String expression) {
//String suffixExpression="";
operateStack.push('#');
//int pos=0;
char[] ex=expression.toCharArray();
for(int i=0;i<ex.length;i++){
boolean flag=true;
if(isOperator(ex[i])){//判断是否是操作符
char top=operateStack.peek();//栈顶的操作符
int sub=get(ex[i]);//操作符在数组中的下标
if(out[sub]>in[get(top)]){//判断该操作符的优先级是否高于栈顶操作符优先级,包括(
operateStack.push(ex[i]);
}else if(ex[i]!=')'&&ex[i]!='#'){
//如果该操作符的优先级低于栈顶操作符的优先级而且该操作符不等于)和#,则执行以下操作
suffixStack.push(String.valueOf(operateStack.pop()));
//suffixExpression=suffixExpression+String.valueOf(operateStack.pop());
i--;
}
while(ex[i]=='#'&&top!='#'){
suffixStack.push(String.valueOf(operateStack.pop()));
//suffixExpression=suffixExpression+String.valueOf(operateStack.pop());
top=operateStack.peek();
}
while(ex[i]==')'&&flag){
if(top!='('){
char b=operateStack.pop();
suffixStack.push(String.valueOf(b));
top=operateStack.peek();
}else{
operateStack.pop();
flag=false;
}
/*if(ex[i]==')')//不清楚这个判断为什么会出错
* while(top!='('&&flag){//持续出栈,直到(出栈,将出栈元素放到后缀表达式中
char b=operateStack.pop();
System.out.println(flag);
suffixStack.push(String.valueOf(b));
//suffixExpression=suffixExpression+String.valueOf(operateStack.pop());
top=operateStack.peek();
if(top=='('){
char a=operateStack.pop();
System.out.println(a);
flag=false;
}
}*/
}
}else{
if(i<1){//防止数组角标越界
suffixStack.push(String.valueOf(ex[i]));
}else if(!isOperator(ex[i-1])){//如果前一位是数字的话,则合并,在表达式里面是多位数
suffixStack.push(suffixStack.pop()+String.valueOf(ex[i]));
}else{
suffixStack.push(String.valueOf(ex[i]));
}
//suffixExpression+=String.valueOf(ex[i]);
}
}
return suffixStack;
}
//计算出栈的两个操作数的运算结果
public int calculate(int one,int two,char c){
//System.out.println(c);
int result=0;
switch(c){
case '+':result=two+one;/*System.out.println(two+"+"+one+"="+result)*/;break;
case '-':result=two-one;break;
case '*':result=two*one;break;
case '/':result=two/one;break;
case '^':result=(int) Math.pow(two, one);break;
}
return result;
}
}
后缀表达式求值
最新推荐文章于 2022-05-19 09:27:20 发布
