• Leetcode 10


    题目

    https://leetcode.com/problems/regular-expression-matching/

    题意

    给出一个模式串P,和一个字符串S。判断字符串S是否符合模式串P。

    P和S要么是空串,要么是小写字母组成的串。

    Example 1:

    Input:
    s = "aa"
    p = "a"
    Output: false
    Explanation: "a" does not match the entire string "aa".
    

    Example 2:

    Input:
    s = "aa"
    p = "a*"
    Output: true
    Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
    

    Example 3:

    Input:
    s = "ab"
    p = ".*"
    Output: true
    Explanation: ".*" means "zero or more (*) of any character (.)".
    

    Example 4:

    Input:
    s = "aab"
    p = "c*a*b"
    Output: true
    Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".
    

    Example 5:

    Input:
    s = "mississippi"
    p = "mis*is*p*."
    Output: false
    

    思路

    author's blog == http://www.cnblogs.com/toulanboy/

    (1) 这个题目非常有意思。对于这个题目,其实可以用形式语言与自动机的知识解决。

    因为我们可以把模式串S对应的NFA(不确定的有穷状态自动机)画出来。

    然后将字符串P代入到这个NFA,假如能到达自动机的终点,那么说明该字符串符合该模式串。

    (2)进一步的,我们可以把NFA看成一张图,这个图代表着状态空间,第i层代表前i个模式字符能代表的字符串,每一个状态都是代表一种类型字符的集合。若是我们的字符串S符合模式串P,那么我们通过深搜到第P.length()层时,S所用的字符数应该是P.length()。 状态空间简图如下:

    屏幕快照 2019-05-17 00.40.28.png

    (3)字符串P代入到这个NFA的过程就等同于在该图中进行深度优先搜索。首先从第1层开始,这时候有新的模式串字符,当字符串P的对应字符和当前模式串字符对应时,则继续往下一层走。依次类推,不停地深度搜索,如果发现这个分支不行,则回退到上一层。如果能走到最后一层,且当前字符串也用完了所有字符,则说明该字符串符合该模式串。

    在遇到新模式串字符时,我们要判断是.还是其他字母。

    (3.1)若是.,则判断后面有无*。若有*则说明任意字符在这里出现多次(注意是0次以上,包含0次)。

    (3.2)若是其他字母,也判断后面有无*。若有*则说明该字符在这里出现多次(注意是0次以上,包含0次)。

    星号的存在意味着某字符出现0次或以上,所以会在该状态产生很多分支。

    我们可以把模式串P的第i个字符看成层次。每一条边都代表模式串的一次状态转移。

    状态空间是模式串的每一个状态。

    代码

    //author's blog == http://www.cnblogs.com/toulanboy/
    class Solution {
    public:
        bool dfs(string s, string p, int i, int j){
            if(i == p.length() && j == s.length())
                return true;
            if(i >= p.length() || j > s.length())
    		    return false;
            //(1)如果遇到.
            if(p[i] == '.'){
                //(1.1) .后没有字符了 或者 .后不是*
                if(i+1 == p.length() || p[i+1] != '*'){
                    return dfs(s, p, i+1, j+1);
                }
                //(1.2) .后是*
                else if(p[i+1] == '*'){
                    //.可以出现0次或多次,所有这里有很多分支
                    while(j <= s.length()){
                        if(dfs(s, p, i+2, j))
                            return true;
                        j++;
                    }
                    return false;
                }
            }
    
            ///(2)如果不是.
            //author's blog == http://www.cnblogs.com/toulanboy/
            else if(p[i] != '.'){
                //(2.1) 该字符后面没有字符了 或者 该字符后面不是*
                if(i+1 == p.length() || p[i+1] != '*'){
                    if(p[i] == s[j]){
                        return dfs(s, p, i+1, j+1);
                    }
                    else
                        return false;
                }
                //(2.2) 该字符后面是*
                else if(p[i+1] == '*'){
                    //该字符出现0次的情况
                    if(dfs(s, p, i+2, j))
                        return true;
                    //该字符出现1次以上的情况
                    while(j < s.length() && p[i] == s[j]){
                        j++;
                        if(dfs(s, p, i+2, j))
                            return true;
                    }
                    return false;
                }
            }
            return false;
        }
        bool isMatch(string s, string p) {
            if(p.length() == 0)
    		    return !s.length();
            return dfs(s, p, 0, 0);
        }
    };
    

    运行结果

    Runtime: 656 ms
    Memory Usage: 166.7 MB
    
  • 相关阅读:
    C#中二进制,八进制,十六进制到十进制的相互转换
    Mac装Win10后没有无线网络的处理
    U盘容纳不了大于4G的文件比如ISO文件咋办?
    经典游戏“大富翁4”存档文件修改器Rich4Editor下载
    向C#的选项卡中添加自定义窗体
    C#对二进制文件的特定位置进行读写小结
    抗战剧中最耐看的《我的团长我的团》,最后结尾依然有神剧的影子
    绝大多数人努力程度之低,根本轮不上拼天赋
    ZT:与其怨天尤人,不如全力以赴;若想改变世界,你必须先从改变自己开始!
    java基础学习_多线程02_多线程、设计模式_day24总结
  • 原文地址:https://www.cnblogs.com/toulanboy/p/10879049.html
Copyright © 2020-2023  润新知