自定义表达式解析之逆波兰表达式

对于需要自定义表达式求值的问题可以将表达式转化成逆波兰表达式,这有利于计算机处理计算问题和优先级问题。

package test;

import java.util.Stack;

/**@类名 ReversePolishNotation
 * @说明 
 * @作者 Fabuler
 * @日期 2017年1月4日-上午10:08:08
 */
public class ReversePolishNotation {
	/**
	 * @名称 precedence
	 * @说明	定义运算符优先级 越小优先级越高
	 * @作者 Fabuler
	 * @日期 2017年1月4日-上午10:10:10
	 * @param sign
	 * @return
	 */
	public int precedence(char sign){
		switch (sign) {
		case '&':
			return 1;
		case '|':
			return 2;
		case '{':
		case '}':
		default:
			return 0;
		}
	}
	/**
	 * 描述:判断是否是操作符
	 * 作者:Fabuler
	 * 日期:2017年1月4日 - 下午9:42:42
	 * @param c
	 * @return
	 */
	public boolean isSign(char c){
		switch (c) {
		case '&':
		case '|':
		case '{':
		case '}':
			return true;
		default:
			return false;
		}
	}
	/**
	 * 描述:将表达式转换为逆波兰表达式
	 * 作者:Fabuler
	 * 日期:2017年1月4日 - 下午9:43:06
	 * @param el
	 * @return
	 */
	public Stack<Object> transform(String el){
		Stack<Object>operand=new Stack<>();
		Stack<Character>operator=new Stack<>();
		//操作数数组
		String[]ods=el.replaceAll("\\{|\\}|\\||\\&", " ").split(" +");
		int odsIndex=0;
		char[]chars=el.toCharArray();
		int l=chars.length;
		for(int i=0;i<l;i++){
			char c=chars[i];
			if(!isSign(c)){
				String od=ods[odsIndex++];
				if(!"".equals(od)){
					operand.push(od);
				}
				i+=od.length()-1;
			}else{
				if(c=='{'){
					operator.add(c);
				}else if(c=='}'){
					char c2=operator.pop();
					while(c2!='{'){
						operand.add(c2);
						if(!operator.isEmpty()){
							c2=operator.pop();
						}else{
							break;
						}
					}
				}else {
					if(operator.isEmpty()){
						operator.add(c);
					}else if(operator.peek()=='{'){
						operator.add(c);
					}else if(precedence(c)<precedence(operator.peek())){
						operator.add(c);
					}else{
						while(!operator.isEmpty()){
                            char c2=operator.peek();
                            if(precedence(c)>=precedence(c2)&&c2!='{'){
                                operand.add(c2);
                                operator.pop();
                            }else{
                                break;
                            }
                        }
						operator.add(c);
					}
				}
			}
		}
		while(!operator.isEmpty()){
			operand.add(operator.pop());
		}
		return operand;
	}
	public static void main(String[] args) {
		ReversePolishNotation rpn=new ReversePolishNotation();
//		String a="21_20&{1_01&{20_12&[0_15,0_31]|20_16}|[21_13,21_15]}";
		String a="a&{b&{c|d}&{e|f&g}}";
//		String a="a|b&e";
//		String a="{~a|b}&e";
		System.out.println(rpn.transform(a));
	}
}

这个算法思想是先将表达式里面的操作数取出到一个数组中,然后再将表达式转换成char数组,遍历这个数组进行转换操作。这里只对二目操作符进行了处理,对一目操作符不处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值