后缀表达式求值

本文介绍了一种使用Java实现的后缀表达式计算方法。通过将中缀表达式转换为后缀表达式,并利用栈数据结构进行计算。文章提供了一个完整的示例程序,包括后缀表达式的生成和求值。
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;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值