10. 正则表达式匹配

10. 正则表达式匹配

题意

给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.''*' 的正则表达式匹配。

'.' 匹配任意单个字符。
'*' 匹配零个或多个前面的元素。

匹配应该覆盖整个字符串 (s) ,而不是部分字符串。

说明:

  • s 可能为空,且只包含从 a-z 的小写字母。

  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 .*

示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

解题思路

需要注意的是,和之前做的题不一样,这里*代表的是匹配前一个字符的0次或者n次,比如a*表示匹配0到n个字符a。

  1. 回溯

    1. 空:如果此时P为空,S也为空,则返回True,相反,如果其中一方为空,一方不为空,则返回False;

    2. 一个字符:如果此时双方都只有一个字符,那么直接比较即可;

    3. 多个字符:有两种情况:如果P的第二个字符不为*,那么比较首字符,然后从双方的下一个位置开始继续的递归比较;如果为*的话,就让S不停的去匹配可能的P中的*,如果S还是无法匹配成功的话,就抛弃掉P中的*,然后让P从后面两个字符继续和当前的S进行比较;

  1. dp

    假定dp[i][j]表示p的第j个字母可以匹配到s的第i个字母,有以下几种情况:

    1. 如果p[j] = s[i]dp[i][j] = dp[i-1][j-1];

    2. 如果p[j] == .dp[i][j] =dp[i-1][j-1]

实现

class Solution(object):
   def isMatch(self, s, p):
       """
      :type s: str
      :type p: str
      :rtype: bool
      """
       if not p:
           return len(s) == 0
       if len(p) == 1:
           return len(s) == 1 and (s[0] == p[0] or p[0] == '.')

       # 不为*则直接比较第一个,然后双方继续递归
       if p[1] != '*':
           return len(s) != 0 and (p[0] == s[0] or p[0] == '.') and self.isMatch(s[1:], p[1:])

       # 剩下的语句说明P存在*
       # S中可能存在多个相同的匹配元素,比如aaaa和a*,S需要一直移动,同时还要在移动的过程中和P的两个字符后面去比较(因为第一个字符已经相等,而第二个字符则为*),只要匹配成功一个,就返回True,反之S会一直移动到为空
       while s and (s[0] == p[0] or p[0] == '.'):
           if self.isMatch(s, p[2:]):
               return True
           s = s[1:]

       # 之前匹配P中的*不成功,且S和P也不能够再匹配了,所以查看下一个P中的*和现在的S来做匹配
       return self.isMatch(s, p[2:])
     
     
def isMatch(self, s, p):
    """
      :type s: str
      :type p: str
      :rtype: bool
      """
       lenS, lenP = len(s), len(p)
       dp = [[False] * (lenP + 1) for i in range(lenS + 1)]

       # initialization, when p is empty, always Flase, when s is empty:
       dp[0][0] = True
       for j in range(2, lenP + 1): dp[0][j] = dp[0][j - 2] and p[j - 1] == '*'

       # dp
       for i in range(1, lenS + 1):
           for j in range(1, lenP + 1):
               dp[i][j] = dp[i][j - 2] or (p[j - 2] in (s[i - 1], '.') and dp[i - 1][j]) if p[j - 1] == '*' \
                   else dp[i - 1][j - 1] and p[j - 1] in ('.', s[i - 1])
       return dp[lenS][lenP]
posted @ 2017-09-04 12:50  banananana  阅读(144)  评论(0)    收藏  举报