给你一个以字符串形式表述的布尔表达式 (boolean)expression,返回该式的运算结果。
有效的表达式需遵循以下约定:
示例 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 是以上述形式给出的有效表达式,表示一个布尔值。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/parsing-a-boolean-expression
(1)栈
思路参考本题官方题解,具体细节见下面代码中的注释。
//思路1————栈
class Solution {
public boolean parseBoolExpr(String expression) {
Stack<Character> stack = new Stack<>();
int length = expression.length();
for (int i = 0; i < length; i++) {
//当前遍历到的字符记为 c
char c = expression.charAt(i);
if (c == ',') {
//',' 只是用于分隔 expr,其对最终结果没有决定性作用,故遇到 ',' 直接跳过
continue;
} else if (c != ')') {
//当前字符不为 ')',则说明当前表达式还未遍历结束
stack.push(c);
} else {
//当前字符为 ')',当前表达式已经遍历结束,依次从栈中取值该表达式,将计算得到的结果重新放入栈中
// 统计当前表达式中 expr 为 true 和 false 的数量,分别用 t 和 f 来表示
int t = 0, f = 0;
while (stack.peek() != '(') {
char val = stack.pop();
if (val == 't') {
t++;
} else {
f++;
}
}
// '(' 栈
stack.pop();
// op 为当前表达式的逻辑运算符
char op = stack.pop();
//根据 op 计算当前表达式的结果,并将其放入栈中
switch (op) {
case '!':
//运算符为 '!',此时 t 和 f 中有且只有一个的值为 1,另外一个为 0
stack.push(f == 1 ? 't' : 'f');
break;
case '&':
//运算符为 '&',则说明只要有一个 f,那么整个表达式的结果就为 t
stack.push(f == 0 ? 't' : 'f');
break;
case '|':
//运算符为 '|',则说明只要有一个 t,那么整个表达式的结果就为 t
stack.push(t > 0 ? 't' : 'f');
break;
default:
}
}
}
//最后栈顶的字符只有两种情况:t 或 f,分别代表 true 和 false
return stack.pop() == 't';
}
}