Leetcode——正则表达式匹配

Posted Yawn,

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode——正则表达式匹配相关的知识,希望对你有一定的参考价值。

1. 正则表达式匹配

(1)递归

以字符串"aaa"和模式串"abac*a"为例:

这里有两种匹配方式:

  • (1)单个匹配,如果两个字符相同,或者模式串当前是万能字符.,则匹配成功,然后继续递归比较 s[i + 1:] 和p[i + 1:]
  • (2)如果模式串后面跟了"*",这又分为两种情况:
    • 1.如果s[i]和p[i]不等(比如aa和b*这种情况),则将b *忽略掉,也就是继续递归比较s和p[i + 2:]
    • 2.如果p[i]和s[i]相等(比如aa和a*这种情况),我们可以选择忽略a * ,也就是执行1,也可以将字符串中的a忽略掉,继续递归比较s[i + 1:]和p
    • 所以递归执行,需要注意当匹配*时候,走的两条分支
class Solution {
    public boolean isMatch(String s, String p) {
        return dfs(new HashMap<>(), s, p);
    }

    public boolean dfs(Map<Pair, Boolean> cache, String s, String p) {
        //pair是一对值,Map是集合
        Pair pair = new Pair(s, p);     

        //加个记忆化,不然纯递归会超时的
        if (cache.containsKey(pair))
            return cache.get(pair);
        
        if (p.isEmpty())
            return s.isEmpty();

        //检查s[0]和p[0]是否匹配
        boolean isFirstMath = s.length() > 0 && (p.charAt(0) == '.' || p.charAt(0) == s.charAt(0));

        //检查模式串的下个字符是否为"*
        boolean isMatchAny = p.length() > 1 && p.charAt(1) == '*';
        if (isMatchAny) {
            //如果包含"*",可以忽略掉当前字符+*
            //也可以忽略掉字符串中的当前字符(如果能匹配上)
            cache.put(pair, dfs(cache, s, p.substring(2)) || (isFirstMath && dfs(cache, s.substring(1), p)) );
        }
        else {
            //单个字符匹配的情况
            cache.put(pair, isFirstMath && dfs(cache, s.substring(1), p.substring(1)) );
        }
        return cache.get(pair);
    }
}

(2)动态规划(后续补充)

以上是关于Leetcode——正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode(算法)- 10. 正则表达式匹配

循环通过 python 正则表达式匹配

LeetCode-010-正则表达式匹配

LeetCode(剑指 Offer)- 19. 正则表达式匹配

leetcode19 正则表达式匹配(Hard)

LeetCode-递归正则表达式匹配