Assume the input string always valid(which means odd position always be operator). We solve problem recursively by check the operator each time:
“|”: leftTrue*rightTrue + leftTrue* rightFalse + leftFalse*rightTrue;
“&” : leftTrue * rightTrue;
“^”: leftTrue*rightFalse + leftFalse*rightTrue;
public static int count = 0;
static boolean stringToBool(String s){
return s.equals("1") ? true : false;
}
public static int cntEval(String s, boolean res, HashMap<String, Integer> mp){
++count;
if(s.length() == 0) return 0;//
if(s.length() == 1) return stringToBool(s) == res ? 1 : 0;
if(mp.containsKey(s+res)) return mp.get(s+res);
int cnt = 0;
for (int i = 1; i<s.length(); i+=2){//only care about the operator character
char c = s.charAt(i);
String left = s.substring(0,i);
String right = s.substring(i+1, s.length());
int leftTrue = cntEval(left, true, mp), leftFalse = cntEval(left, false, mp);
int rightTrue = cntEval(right,true, mp), rightFalse = cntEval(right,false,mp);
int total = (leftTrue + leftFalse) * (rightTrue + rightFalse);
int totalTrue = 0;
if(c=='^'){
totalTrue = leftTrue * rightFalse + leftFalse * rightTrue;
}else if(c=='|'){
totalTrue = leftTrue * rightTrue + leftFalse * rightTrue + leftTrue * rightFalse;
}else if(c=='&'){
totalTrue = leftTrue * rightTrue;
}
int ways = res ? totalTrue : total - totalTrue;
cnt += ways;
}
mp.put(s+res,cnt);
return cnt;
}
public static int countEval(String s, boolean result) {
return cntEval(s, result, new HashMap<String, Integer>());
}
public static void main(String[] args) {
String expression = "0^0|1&1^1|0|1";
boolean result = true;
System.out.println(countEval(expression, result));
System.out.println(count);
}