给你一个以字符串形式表述的布尔表达式,返回该式的运算结果。
有效的表达式需遵循以下约定:
"t"
,运算结果为True
"f"
,运算结果为False
"!(expr)"
,运算过程为对内部表达式expr
进行逻辑 非的运算(NOT)"&(expr1,expr2,...)"
,运算过程为对 2 个或以上内部表达式expr1, expr2, ...
进行逻辑 与的运算(AND)"|(expr1,expr2,...)"
,运算过程为对 2 个或以上内部表达式expr1, expr2, ...
进行逻辑 或的运算(OR)
示例 1:
输入:expression = "!(f)"
输出:true
示例 2:
输入:expression = "|(f,t)"
输出:true
示例 3:
输入:expression = "&(t,f)"
输出:false
示例 4:
输入:expression = "|(&(t,f,t),!(t))"
输出:false
提示:
1 <= expression.length <= 20000
-
expression[i]
由{'(', ')', '&', '|', '!', 't', 'f', ','}
中的字符组成。 -
expression
是以上述形式给出的有效表达式,表示一个布尔值。
思路:递归
- 如果只有一个字符,即t或f,直接得到结果
- 如果有多个字符,必然以
!
、&
、|
开头-
!
:将原字符串剔除括号,再进行计算,返回结果的not -
&
:将&
括号中的内容拆开,得到多个表达式,分别计算多个表达式并做与运算(这里就是括号很复杂) -
|
同理
-
class Solution {
public boolean parseBoolExpr(String expression) {
if (expression.length() == 1) {
return expression.equals("t");
} else {
char c = expression.charAt(0);
String subExp = expression.substring(2, expression.length() - 1);
if (c == '!') {
return !parseBoolExpr(subExp);
} else if (c == '&') {
return parseAnd(subExp);
} else if (c == '|') {
return parseOr(subExp);
}
}
return false;
}
private boolean parseAnd(String expression) {
String[] split = split(expression);
boolean result = parseBoolExpr(split[0]);
for (int i = 1; i < split.length; i++) {
result &= parseBoolExpr(split[i]);
if (!result) {
return false;
}
}
return result;
}
private boolean parseOr(String expression) {
String[] split = split(expression);
boolean result = parseBoolExpr(split[0]);
for (int i = 1; i < split.length; i++) {
result |= parseBoolExpr(split[i]);
if (result) {
return true;
}
}
return result;
}
/*
* 想根据逗号把字符串分开,奈何不会正则
* 如 f,&(t,t) 分成f、&(t,t)
* */
private String[] split(String expression) {
if (!expression.contains("(")) {
return expression.split(",");
}
String[] splits = new String[10];
int count = 0;
String subExp = expression;
while (true) {
int dotIndex = subExp.indexOf(',');
if (dotIndex > 0) {
String subStr = subExp.substring(0, dotIndex);
if (!subStr.contains("(")) {
splits[count++] = subStr;
subExp = subExp.substring(dotIndex + 1);
continue;
}
}
int rightIndex = matchBracket(subExp);
splits[count++] = subExp.substring(0, rightIndex + 1);
if (rightIndex == subExp.length() - 1) {
break;
}
subExp = subExp.substring(rightIndex + 2);
}
String[] ans = new String[count];
System.arraycopy(splits, 0, ans, 0, count);
return ans;
}
private int matchBracket(String expression) {
int count = 1;
int index = 2;
while (count != 0) {
if (expression.charAt(index) == '(') {
count++;
} else if (expression.charAt(index) == ')') {
count--;
}
index++;
}
return index - 1;
}
public static void main(String[] args) {
Solution solution = new Solution();
String expression = "!(&(!(&(f)),&(t),|(f,f,t)))";
// String expression="|(&(t,f,t),!(t))";
// String expression="|(f,&(t,t))";
System.out.println(solution.parseBoolExpr(expression));
}
}