The Indian Engineer

Problem 1106 Parsing A Boolean Expression

Posted on 6 mins

String Stack Recursion

Problem Statement

Link - Problem 1106

Question

A boolean expression is an expression that evaluates to either true or false. It can be in one of the following shapes:

Given a string expression that represents a boolean expression, return the evaluation of that expression.

It is guaranteed that the given expression is valid and follows the given rules.

Example 1:

Input: expression = "&(|(f))"
Output: false
Explanation: 
First, evaluate |(f) --> f. The expression is now "&(f)".
Then, evaluate &(f) --> f. The expression is now "f".
Finally, return false.

Example 2:

Input: expression = "|(f,f,f,t)"
Output: true
Explanation: The evaluation of (false OR false OR false OR true) is true.

Example 3:

Input: expression = "!(&(f,t))"
Output: true
Explanation: 
First, evaluate &(f,t) --> (false AND true) --> false --> f. The expression is now "!(f)".
Then, evaluate !(f) --> NOT false --> true. We return true.

Constraints:

Solution

class Solution {
public:
    static bool parseBoolExpr(string& expr) {
        vector<char> stack;
        stack.reserve(expr.size());
        for (char c : expr) {
            switch (c) {
            case ',': break;
            case ')': {
                char s;
                vector<char> x;
                char t = stack.back();
                x.push_back(t);
                stack.pop_back();
                while (t != '(') {
                        x.push_back(t);
                        t = stack.back();
                        stack.pop_back();
                }
                char op = stack.back();
                stack.pop_back();
                switch (op) {
                case '!':
                    s = (x[0] == 'f') ? 't' : 'f';
                    break;
                case '&':
                    s = all_of(x.begin(), x.end(),[](char b) { return b == 't'; })? 't': 'f';
                    break;
                case '|':
                    s = any_of(x.begin(), x.end(),[](char b) { return b == 't'; })? 't': 'f';
                    break;
                }
                stack.push_back(s);
                break;
            }
            default:
                stack.push_back(c);
            }
        }
        return stack.back() == 't';
    }
};

Complexity Analysis

| Algorithm                         | Time Complexity | Space Complexity |
| --------------------------------- | --------------- | ---------------- |
| Stack-based Expression Evaluation | O(n)            | O(n)             |

Explanation

Intial Thoughts

To solve this problem, we should start by breaking down the boolean expression into its simplest components. This involves identifying the logical operators such as NOT, AND, and OR, and the boolean values true and false. We should think about how these operators interact with each other, like how NOT flips the value, AND requires all to be true, and OR requires at least one to be true. We should also consider how to handle nested expressions, thinking of them like layers of an onion that we peel back one at a time. A stack data structure could be useful here because we can push and pop elements as we encounter opening and closing parentheses, allowing us to process the expression from the innermost outwards.

Intuitive Analysis

Intuitively, we can think of solving this problem as if we’re following a recipe. First, we identify the ingredients, which are the boolean values and the operators. Then, we follow the order of operations, similar to how we follow steps in a recipe. We start with the innermost parentheses and work our way outwards, applying the operators as we go. The stack helps us keep track of where we are in the recipe, allowing us to temporarily set aside parts of the expression and come back to them later. We can also think of each operator as a filter that changes the boolean values as it encounters them. By thinking about the problem in this step-by-step, methodical way, we can break down even the most complex boolean expressions into manageable parts.

1. Intuition

2. Implementation


Complexity Analysis

Time Complexity:

Space Complexity:


Footnote

This question is rated as Hard difficulty.

Hints

Write a function “parse” which calls helper functions “parse_or”, “parse_and”, “parse_not”.