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

题目介绍

请实现一个函数用来匹配包括 . 和 * 的正则表达式。
模式中的字符 . 表示任意一个字符而 * 表示它前面的字符可以出现任意次(包含0次)
在本题中,匹配是指字符串的所有字符匹配整个模式。

字符串"aaa"与模式"a.a"和"ab*ac*a"匹配;
字符串"aaa"与"aa.a"和"ab*a"均不匹配。

题目解读

我们可以先从 * 字符进行入手,因为 * 字符相对于 . 字符来说较为复杂,情况也更多
首先按第一个字符后是否为 * 字符,分为两种情况,再对这两种情况进行讨论。

1.首字符后(也就是第二个字符)为 * 字符时,这种情况下我们会再进行一次判断:
判断字符串和pattern的首字符是否相等,如果不相等,我们只有将pattern后移两个字符,才有匹配成功的可能;
如果首字符相等 ( . 也可以看作相等),那么又会有以下三种匹配模式:

  • 直接跳过pattern的前两个字符,也就是 * 前面的字符看作出现0次;
  • 字符串后移一个字符,pattern后移两个字符,即将 * 前面出现的字符看作出现一次;
  • 字符串后移一个字符,pattern保持不动,即将 * 前面的字符看作出现多次;

结合下面四个例子,会看得比较清晰:

字符串为“aabb”
pattern1: c*aabb 	首字符不相等,只能将pattern后移两个字符;
pattern2: a*aabb 	此时首字符虽然相等,但也需要把 * 前面的字符看作出现0次,才能匹配成功;
pattern3: a*abb		首字符相等,把 * 前面的字符看作出现1次,进行正常匹配;
pattern4: a*bb		首字符相等,但这时需要把 * 前面的字符看作出现多次(2次及以上),才能进行匹配。

以上4种情况,只要到最后任一匹配成功,就返回True。

2.首字符后(也就是第二个字符)不为 * 字符时,我们就可以直接比较字符串和pattern两个首字符:

  • 若相等,两者都后移一个字符,进行下一轮比较;
  • 若不等,可直接返回False。
字符串为“abcd”
pattern1: abcd		首字符都为a,判断下一个字符;
pattern2: bbcd		首字符不相等,直接返回False。

代码解析

    def match(self, s, pattern):
    	# 递归终止条件
        if s == pattern: return True
        if not pattern: return False
        # 判断第二个字符是否为 *
        if len(pattern)>1 and pattern[1] == '*':
        	# 判断首字符是否相等,不要忘记 . 的情况
            if s and (pattern[0] == s[0] or pattern[0] == '.'):
            	# 相等的情况下,三种匹配模式
                return self.match(s[1:],pattern[2:]) \
                        or self.match(s,pattern[2:]) \
                        or self.match(s[1:], pattern)
            else:
            	# 不等时,只能将pattern后移,继续判断
                return self.match(s, pattern[2:])
        # 第二个字符不为 *,直接对首字符进行比较    
        elif s and (s[0] == pattern[0] or pattern[0] == '.'):
            return self.match(s[1:], pattern[1:])
    
        return False

你可能感兴趣的:(剑指Offer)