对于需要自定义表达式求值的问题可以将表达式转化成逆波兰表达式,这有利于计算机处理计算问题和优先级问题。
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数组,遍历这个数组进行转换操作。这里只对二目操作符进行了处理,对一目操作符不处理。