[LeetCode] 1106. Parsing A Boolean Expression 解析一個布爾型表達式



Return the result of evaluating a given boolean expression, represented as a string.

An expression can either be:

  • "t", evaluating to True;
  • "f", evaluating to False;
  • "!(expr)", evaluating to the logical NOT of the inner expression expr;
  • "&(expr1,expr2,...)", evaluating to the logical AND of 2 or more inner expressions expr1, expr2, ...;
  • "|(expr1,expr2,...)", evaluating to the logical OR of 2 or more inner expressions expr1, expr2, ...

Example 1:

Input: expression = "!(f)"
Output: true

Example 2:

Input: expression = "|(f,t)"
Output: true

Example 3:

Input: expression = "&(t,f)"
Output: false

Example 4:

Input: expression = "|(&(t,f,t),!(t))"
Output: false

Constraints:

  • 1 <= expression.length <= 20000
  • expression[i] consists of characters in {'(', ')', '&', '|', '!', 't', 'f', ','}.
  • expression is a valid expression representing a boolean, as given in the description.

這道題說是給了一個布爾型的表達式,讓我們進行解析,並返回最終的值。其中的t和f分別表示 true 和 false,這里還有其他三種操作符,與,或,和非,這些都是最基本的邏輯運算,沒有太大的難度。這道題的難點在於給定的是一個字符串,而且可能出現嵌套的運算,比如例子4,運算順序應該是從內而外的。如何才能拆分出正確的邏輯塊並進行運算是一個難點,由於存在嵌套,所以從左到右遍歷的話可能會遇到很多的左括號,什么時候知道遇到最內層的邏輯塊了呢,就是第一次遇到右括號的時候,這樣跟之前一個左括號之間的內容一定是當前最內層的邏輯塊了,可以進行計算了。所以右括號的位置是一個觸發點,並且需要回溯到前一個左括號的位置,這種后進先出的特點可以使用棧來做。所以大體是思路就有了,遍歷表達式的每一個字符,只要遇到的不是右括號或者逗號(逗號入棧沒有意義,可以直接忽略),就壓入棧。若遇到了右括號,則此時要出棧,直至到上一個左括號,中間的可能有大量的t和f,重復出現的不影響結果,可以將所有內容放入到一個 HashSet 中,這樣方便之后查找。當對應的左括號也出棧之后,接下來棧頂的就是操作符了,將其出棧,並且根據其不同進行邏輯運算:若是與運算,則只要看 HashSet 中是否有 false,有的話結果就是 false,壓入棧;若是或運算,只要看 HashSet 中是否有 true,有的話就是 true,壓入棧。若是非運算,則 HashSet 中只有一個布爾型變量,對其取反並壓入棧。最終遍歷完成后,棧中只會剩余一個布爾型變量,根據其結果返回對應的 true 或者 false 即可,參見代碼如下:


class Solution {
public:
    bool parseBoolExpr(string expression) {
        stack<char> st;
        for (int i = 0; i < expression.size(); ++i) {
            char c = expression[i];
            if (c == ')') {
                unordered_set<char> seen;
                while (!st.empty() && st.top() != '(') {
                    seen.insert(st.top()); st.pop();
                }
                st.pop();
                char op = st.top(); st.pop();
                if (op == '&') {
                    st.push(seen.count('f') ? 'f' : 't');
                } else if (op == '|') {
                    st.push(seen.count('t') ? 't' : 'f');
                } else {
                    st.push(seen.count('t') ? 'f' : 't');
                }
            } else if (c != ',') {
                st.push(c);
            }
        }
        return st.top() == 't';
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1106


參考資料:

https://leetcode.com/problems/parsing-a-boolean-expression/

https://leetcode.com/problems/parsing-a-boolean-expression/discuss/323307/Python-Easy-1-line-Cheat

https://leetcode.com/problems/parsing-a-boolean-expression/discuss/323532/JavaPython-3-Iterative-and-recursive-solutions-w-explanation-and-analysis.


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM