您的位置:首页 > 编程语言 > Python开发

【LeetCode with Python】 Regular Expression Matching

2008-09-13 00:46 579 查看
博客域名:http://www.xnerv.wang

原题页面:https://oj.leetcode.com/problems/regular-expression-matching/

题目类型:动态规划

难度评价:★★★★

本文地址:/article/1377560.html

Implement regular expression matching with support for
'.'
and
'*'
.

'.' Matches any single character.'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true


Wildcard Matching这道题类似,动态规划算法本身已经不是难点,关键在于最好对一些特殊cases做预处理:

模式串p中连续的*对可以合并成一个,如a*a*可以合并为a*,而.*.*也可以合并为.*
模式串p中实体字符(不带*)的个数大于字符串s的长度时,匹配失败
模式串p中没有任何实体字符,而字符串s长度为0时,匹配成功

class Solution:

    class Item:
        def __init__(self, char, symbol):
            self.char = char
            self.symbol = symbol

    def splitStr(self, str):
        items = [ ]
        index = 0
        len_str = len(str)
        while index < len_str:
            if index + 1 >= len_str or '*' != str[index + 1]:
                items.append(Solution.Item(str[index], ''))
                index += 1
            else:
                items.append(Solution.Item(str[index], '*'))
                index += 2
        return items

    # @param s, an input string
    # @param p, a pattern string
    # @return a boolean
    def isMatch(self, s, p):
        if '' == s and '' == p:
            return True
        p_arr = self.splitStr(p)
        len_s = len(s)
        len_p_arr = len(p_arr)

        last_item = Solution.Item(None, None)
        p_char_num = 0
        new_p_arr = [ ]
        for i in range(0, len_p_arr):
            if last_item.char == p_arr[i].char and last_item.symbol == p_arr[i].symbol and '*' == p_arr[i].symbol:
                pass
            else:
                new_p_arr.append(p_arr[i])
            last_item = p_arr[i]
            if '' == p_arr[i].symbol:
                p_char_num += 1
        if p_char_num > len_s:
            return False
        if 0 ==p_char_num and 0 == len_s:
            return True

        F = [[False for j in range(0, len_p_arr + 1)] for i in range(0, 2)]
        
        # 3 cases for True:
        #    last ch matched, and this ch matcheds (right-down)
        #    p comes x*, and last matched (right)
        #    last p.symbol is x*, s comes matched ch x, and last matched (down)
        for i in range(1, len_s + 1):
            if 1 == i:
                F[0][0] = True
                for j in range(1, len_p_arr + 1):
                    F[0][j] = (F[0][j - 1] and '*' == p_arr[j - 1].symbol)
            else:
                for j in range(0, len_p_arr + 1):          # cannot be F[0] = F[1]
                    F[0][j] = F[1][j]
            F[1][0] = False
            for j in range(1, len_p_arr + 1):
                if True == F[0][j - 1] and (p_arr[j - 1].char == s[i - 1] or '.' == p_arr[j - 1].char):
                    F[1][j] = True
                elif True == F[1][j - 1] and '*' == p_arr[j - 1].symbol:
                    F[1][j] = True
                elif True == F[0][j] and (s[i - 1] == p_arr[j - 1].char  or '.' == p_arr[j - 1].char)and '*' == p_arr[j - 1].symbol:
                    F[1][j] = True
                else:
                    F[1][j] = False

        return F[1][len_p_arr]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: