最近用到逻辑组合关系运算,顺手写了个测试的方法。记录下。未完全测试。有问题,欢迎指正。
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class Test {
private static Map<String,Boolean> cache = new HashMap<String,Boolean>();
static{
cache.put("111", true);
cache.put("112", false);
cache.put("113", true);
cache.put("114", false);
cache.put("115", true);
cache.put("116", true);
cache.put("117", true);
}
/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
String reg = "!(117&115)|117";
System.out.println(combineOpt(reg));
}
/**
* 逻辑运算
* @param cond1
* @param cond2
* @param logicOpt
* @return
*/
public static boolean logicCalc(boolean cond1,boolean cond2,char logicOpt){
if('&' == logicOpt){
return cond1 && cond2;
}else if('|' == logicOpt){
return cond1 || cond2;
}else if('!' == logicOpt){
return !cond1 ;
}
return false;
}
/**
* 组合操作
* @param express
* @return
*/
public static boolean combineOpt(String express) throws Exception{
int len = express.length();
char c,tempChar;
Stack<Character> opt = new Stack<Character>();
Stack<Boolean> coll = new Stack<Boolean>();
int lastIdx = -1;
for(int i = 0 ; i < len ; i++){
c = express.charAt(i);
if(Character.isDigit(c)){//如果为数字
lastIdx = judgeNumberPosition(express,i);
String number = express.substring(i, lastIdx);
coll.push(cache.get(number));
i = lastIdx - 1;
}else if(isOptFlag(c)){//如果为操作符
while(!opt.isEmpty() && opt.peek() != '(' && priorityCompare(c,opt.peek()) <= 0 ){//当前操作符优先级大于栈顶操作符优先级则直接入栈
if('!' == opt.peek()){ //如果为!则只要弹出一个操作数
if(!coll.isEmpty()){
boolean b1 = coll.pop();
coll.push(logicCalc(b1,false,opt.pop()));
}else{
break;
}
}else{
boolean b1 = coll.pop();
boolean b2 = coll.pop();
coll.push(logicCalc(b1,b2,opt.pop()));
}
}
opt.push(c);
}else if(c == '('){//"("
opt.push(c);
}else if(c == ')'){//")"
while((tempChar = opt.pop()) != '('){
if('!' == tempChar){
boolean b1 = coll.pop();
coll.push(logicCalc(b1,false,tempChar));
}else{
boolean b1 = coll.pop();
boolean b2 = coll.pop();
coll.push(logicCalc(b1,b2,tempChar));
}
if(opt.isEmpty()){
throw new Exception("opt is empty!");
}
}
}else if(c == ' ') {//' '
}else{
throw new Exception("no match opt!");
}
}
while(!opt.isEmpty()){
tempChar = opt.pop();
if('!' == tempChar){
boolean b1 = coll.pop();
coll.push(logicCalc(b1,false,tempChar));
}else{
boolean b1 = coll.pop();
boolean b2 = coll.pop();
coll.push(logicCalc(b1,b2,tempChar));
}
}
boolean result = coll.isEmpty() ? false : coll.pop();
return result;
}
/**
* 操作符的优先级比较
* @param op1
* @param op2
* @return
*/
private static int priorityCompare(char op1, char op2) {
switch (op1) {
case '&': case '|':
return (op2 == '!' ? -1 : 0);
case '!':
return (op2 == '&' || op2 == '|' ? 1 : 0);
}
return 1;
}
/**
* 判断是否为逻辑运算符号
* @param c
* @return
*/
private static boolean isOptFlag(char c) {
return (c=='&' || c=='|' || c=='!');
}
/**
* 判断一个完整数字的长度
* @param express
* @param start
* @return
*/
public static int judgeNumberPosition(String express,int start){
char c ;
int len = express.length();
for(int i = start; i<len ; i++){
c = express.charAt(i);
if(!Character.isDigit(c)){
return i;
}else if(i == len - 1){
return len;
}
}
return 0;
}
}