正則表達式匹配

leetcode上面的題目解題及重構
題幹:給定一個字符串 (s) 和一個字符模式 (p)。實現支持 '.' 和 '*' 的正則表達式匹配。

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

匹配應該覆蓋整個字符串 (s) ,而不是部分字符串。
說明:
s 可能爲空,且只包含從 a-z 的小寫字母。
p 可能爲空,且只包含從 a-z 的小寫字母,以及字符 . 和 *。
題目及示例傳送門

如果直接用re,那這題就沒意義了,所以肯定要自己寫匹配算法
第一次成功提交代碼:

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

執行用時:1100 ms,執行效率算很差,只能超過32%的提交效率
優化後第二次提交:

def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        if p == "":
            return s == ""
        if len(p) == 1:
            return False if len(s) != 1 else (s == p or p == "." or p == "*")
        if (p[-1] != '*') and (p[-1] != '.') and (p[-1] not in s): 
            return False 
        if (p[1] != '*'): 
            if (len(s) > 0) and ((p[0] == s[0]) or (p[0] == '.')): 
                return self.isMatch(s[1:], p[1:]) 
            else:
                return False

        else: 
            while (len(s) > 0) and ((p[0] == s[0]) or (p[0] == '.')): 
                if (self.isMatch(s, p[2:])): 
                    return True 
                s = s[1:] 
            return self.isMatch(s, p[2:])

執行用時間優化到140 ms,但也只能超過40%的提交效率

把別人提交的效率最高的代碼貼出來:

class Solution(object):
    def isMatch(self, s, p, memo={("",""):True}):
        if not p and s:      return False
        if not s and p:      return set(p[1::2]) == {"*"} and not (len(p) % 2)
        if (s,p) in memo:    return memo[s,p]

        char, exp, prev = s[-1], p[-1], 0 if len(p) < 2 else p[-2]
        memo[s,p] =\
               (exp == '*' and ((prev in {char, '.'} and self.isMatch(s[:-1], p, memo)) or self.isMatch(s, p[:-2], memo)))\
               or\
               (exp in {char, '.'} and self.isMatch(s[:-1], p[:-1], memo))
        return memo[s,p]

執行只用36ms

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章