Input: expression = "!(f)"
Output: true
Input: expression = "|(f,t)"
Output: true
Input: expression = "&(t,f)"
Output: false
Input: expression = "|(&(t,f,t),!(t))"
Output: false
class Solution
{
// IN: string with coma separated BOOL expressions
// OUT: list of corresponding BOOL values
list<bool> deduceBoolList(string exprs)
{
list<bool> res;
const char *c_exprs = exprs.c_str();
do
{
//if we are on coma. step over it
if(*c_exprs == ',')
c_exprs++;
//if we have an operator with argumets
if(c_exprs[1] == '(')
{
//to find the end, we must count every ()
const char *exp_end = c_exprs+2;
size_t active_parentheses_num = 1;
while(active_parentheses_num)
{
exp_end++;
if(*exp_end == '(')
active_parentheses_num++;
if(*exp_end == ')')
active_parentheses_num--;
}
//when end is found form string with whole expression
string exp(c_exprs, exp_end-c_exprs+1);
res.push_back(parseBoolExpr(exp));
c_exprs = exp_end+1;
}
else
{
string exp(1,*c_exprs);
res.push_back(parseBoolExpr(exp));
}
}
while(c_exprs = strchr(c_exprs, ','));
return res;
}
using fbbb = function<bool(bool,bool)>;
public:
bool parseBoolExpr(string expression)
{
if(expression == "f")
return false;
if(expression == "t")
return true;
//3 chars: !()
string in_parentheses = expression.substr(2, expression.size() - 3);
//check for !
if(expression.front() == '!')
return !parseBoolExpr(in_parentheses);
//else we have & or |
list<bool> values = deduceBoolList(in_parentheses);
auto operation = expression.front() == '&' ?
(fbbb)bit_and<bool>() :
bit_or<bool>();
return std::accumulate(values.begin(), values.end(), values.front(),
operation);
}
};