题目地址:
https://leetcode.com/problems/parsing-a-boolean-expression/
给定一个表达式,该表达式是个类似于前缀表达式的布尔表达式,其中't'
代表true,'f'
代表false,其定义是递归的:
1、单个't'
或者'f'
是个表达式;
2、如果expr
是个表达式,则'!(expr)'
,'&(expr,expr,...)'
和'|(expr,expr,...)'
都是个表达式。
求该表达式的值。
思路和表达式求值类似,只不过这里不需要考虑优先级的问题。开两个栈,一个存操作数(即't'
和'f'
)以及左括号'('
(这是因为要标记一下做运算的操作数是哪些),另一个存操作符(即'!'
,'&'
和'|'
)。遇到逗号则直接跳过。遇到右括号的时候开始计算,先pop出操作符和一个操作数,如果操作符是'!'
,则直接将那个操作数取非入操作数栈(当然要先把左括号pop掉再入栈);如果操作符是另外两个,则将操作数的最上面的左括号之上的所有数进行那个运算,再pop出左括号,再将计算结果入栈。最后操作数栈内就保存了运算答案。代码如下:
class Solution {
public:
bool parseBoolExpr(string e) {
stack<char> ops, stk;
for (int i = 0; i < e.size(); i++) {
char ch = e[i];
if (ch == ',') continue;
if (ch == '|' || ch == '&' || ch == '!') ops.push(ch);
else if (ch == '(' || ch == 't' || ch == 'f') stk.push(ch);
else {
// 此时ch是')',需要求解
char op = ops.top(); ops.pop();
char x = stk.top(); stk.pop();
bool cur = x == 't';
if (op == '!') {
// pop掉'('
stk.pop();
stk.push(cur ? 'f' : 't');
} else {
while (stk.top() != '(') {
op == '&' ? cur &= stk.top() == 't' : cur |= stk.top() == 't';
stk.pop();
}
stk.pop();
stk.push(cur ? 't' : 'f');
}
}
}
return stk.top() == 't';
}
};
时空复杂度 O ( n ) O(n) O(n), n n n是表达式长度。
也可以用递归来做。代码如下:
class Solution {
public:
bool dfs(int &k, string& s) {
if (s[k] == 't') {
k++;
return true;
}
if (s[k] == 'f') {
k++;
return false;
}
char op = s[k];
k += 2;
bool res = op == '&';
while (s[k] != ')') {
if (s[k] == ',') k++;
else {
bool t = dfs(k, s);
if (op == '&') res &= t;
else res |= t;
}
}
k++;
if (op == '!') res = !res;
return res;
}
bool parseBoolExpr(string e) {
int k = 0;
return dfs(k, e);
}
};
时空复杂度一样。