zoukankan      html  css  js  c++  java
  • [LeetCode] Ternary Expression Parser 三元表达式解析器

    Given a string representing arbitrarily nested ternary expressions, calculate the result of the expression. You can always assume that the given expression is valid and only consists of digits 0-9?:T and F (T and Frepresent True and False respectively).

    Note:

    1. The length of the given string is ≤ 10000.
    2. Each number will contain only one digit.
    3. The conditional expressions group right-to-left (as usual in most languages).
    4. The condition will always be either T or F. That is, the condition will never be a digit.
    5. The result of the expression will always evaluate to either a digit 0-9T or F.

    Example 1:

    Input: "T?2:3"
    
    Output: "2"
    
    Explanation: If true, then result is 2; otherwise result is 3.
    

    Example 2:

    Input: "F?1:T?4:5"
    
    Output: "4"
    
    Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as:
    
                 "(F ? 1 : (T ? 4 : 5))"                   "(F ? 1 : (T ? 4 : 5))"
              -> "(F ? 1 : 4)"                 or       -> "(T ? 4 : 5)"
              -> "4"                                    -> "4"
    

    Example 3:

    Input: "T?T?F:5:3"
    
    Output: "F"
    
    Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as:
    
                 "(T ? (T ? F : 5) : 3)"                   "(T ? (T ? F : 5) : 3)"
              -> "(T ? F : 3)"                 or       -> "(T ? F : 5)"
              -> "F"                                    -> "F"
    

    这道题让我们解析一个三元表达式,我们通过分析题目中的例子可以知道,如果有多个三元表达式嵌套的情况出现,那么我们的做法是从右边开始找到第一个问号,然后先处理这个三元表达式,然后再一步一步向左推,这也符合程序是从右向左执行的特点。那么我最先想到的方法是用用一个stack来记录所有问号的位置,然后根据此问号的位置,取出当前的三元表达式,调用一个eval函数来分析得到结果,能这样做的原因是题目中限定了三元表达式每一部分只有一个字符,而且需要分析的三元表达式是合法的,然后我们把分析后的结果和前后两段拼接成一个新的字符串,继续处理之前一个问号,这样当所有问号处理完成后,所剩的一个字符就是答案,参见代码如下:

    解法一:

    class Solution {
    public:
        string parseTernary(string expression) {
            string res = expression;
            stack<int> s;
            for (int i = 0; i < expression.size(); ++i) {
                if (expression[i] == '?') s.push(i);
            }
            while (!s.empty()) {
                int t = s.top(); s.pop();
                res = res.substr(0, t - 1) + eval(res.substr(t - 1, 5)) + res.substr(t + 4);
            }
            return res;
        }
        string eval(string str) {
            if (str.size() != 5) return "";
            return str[0] == 'T' ? str.substr(2, 1) : str.substr(4);
        }
    };

    下面这种方法也是利用栈stack的思想,但是不同之处在于不是存问号的位置,而是存所有的字符,将原数组从后往前遍历,将遍历到的字符都压入栈中,我们检测如果栈首元素是问号,说明我们当前遍历到的字符是T或F,然后我们移除问号,再取出第一部分,再移除冒号,再取出第二部分,我们根据当前字符来判断是放哪一部分进栈,这样遍历完成后,所有问号都处理完了,剩下的栈顶元素即为所求:

    解法二:

    class Solution {
    public:
        string parseTernary(string expression) {
            stack<char> s;
            for (int i = expression.size() - 1; i >= 0; --i) {
                char c = expression[i];
                if (!s.empty() && s.top() == '?') {
                    s.pop();
                    char first = s.top(); s.pop();
                    s.pop();
                    char second = s.top(); s.pop();
                    s.push(c == 'T' ? first : second);
                } else {
                    s.push(c);
                }
            }
            return string(1, s.top());
        }
    };

    下面这种方法更加简洁,没有用到栈,但是用到了STL的内置函数find_last_of,用于查找字符串中最后一个目前字符串出现的位置,这里我们找最后一个问号出现的位置,刚好就是最右边的问号,我们进行跟解法一类似的处理,拼接字符串,循环处理,参见代码如下:

    解法三:

    class Solution {
    public:
        string parseTernary(string expression) {
            string res = expression;
            while (res.size() > 1) {
                int i = res.find_last_of("?");
                res = res.substr(0, i - 1) + string(1, res[i - 1] == 'T' ? res[i + 1] : res[i + 3]) + res.substr(i + 4);
            }
            return res;
        }
    };

    参考资料:

    https://discuss.leetcode.com/topic/64389/easy-and-concise-5-lines-python-java-solution

    https://discuss.leetcode.com/topic/64409/very-easy-1-pass-stack-solution-in-java-no-string-concat/2

    LeetCode All in One 题目讲解汇总(持续更新中...)

  • 相关阅读:
    Python相关数据结构的排序
    使用OpenCV和Python构建运动热图视频
    使用AI来检测违反社交距离的行为
    基于Python、Keras和OpenCV的实时人脸活体检测
    每个人都应该知道的十大OpenCV函数
    入门用Python进行Web爬取数据:为数据科学项目提取数据的有效方法
    入门深度学习?这里有5件你应该知道的事
    基于YoloV3卫星图像的储油罐容积占用率研究
    生产中的NLP:创建Docker镜像
    使用Python可视化Word2vec的结果
  • 原文地址:https://www.cnblogs.com/grandyang/p/6022498.html
Copyright © 2011-2022 走看看