10. Regular Expression Matching

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012033124/article/details/80317136

https://leetcode.com/problems/regular-expression-matching/description/

题目大意:给一个字符串s和模式串p,求s是否匹配p
这里要注意的是“*”表示前面的字符可以重复0到无数次,并不是传统意义上的通配符。

解题思路1(递归):把x*(x为任意字符),当做一个整体,这是最难处理的部分,因为x可以重复0到无数次。
我们先来判断p是否为空,若为空则根据s的为空的情况返回结果。当p的第二个字符为*号时,由于*号前面的字符的个数可以任意,可以为0,那么我们先用递归来调用为0的情况,就是直接把这两个字符去掉再比较,或者当s不为空,且第一个字符和p的第一个字符相同时,我们再对去掉首字符的s和p调用递归,注意p不能去掉首字符,因为*号前面的字符可以有无限个;如果第二个字符不为*号,那么我们就老老实实的比较第一个字符,然后对后面的字符串调用递归

代码:

class Solution:
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        if not p:
            return not s
        #为了使代码简洁,第一位字符匹配的结果用first_match代替
        first_match = bool(s) and (s[0] == p[0] or p[0] == '.')

        if len(p) >= 2 and p[1] == '*':  #如果在p中检测到“x*”型字段
            return self.isMatch(s, p[2:]) or first_match and self.isMatch(s[1:], p)
        else:
            return first_match and self.isMatch(s[1:], p[1:])

解题思路2(DP):
用二维矩阵dp记录,dp[i][j]的布尔值表示s[0..i)是否与p[0..j)匹配(注意右边是开区间),初始值为False。
初始状态:令dp[0][0]为true,i=0表示s为空,j=0表示p为空,s、p都为空的时候是匹配的。
重点还是处理x*类型的p串:
例如
判断“a”和“aa*”是否匹配

s=“a a a” , i=1(注意前面表述是开区间)
   ^
p=“a a *” , j=3
       ^

若1)a*匹配0次,则j回退两位,i不动:

s=“a a a” , i=1
   ^
p=“a a *” , j=1
   ^

若“a”和“a”匹配,则“a”和“aa*”匹配。
即dp[i][j]的状态和dp[i][j-2]是相同的,推导得dp[i][j] = dp[i][j-2]

判断“aa”和“aa*”是否匹配

s=“a a a” , i=2
     ^
p=“a a *” , j=3
       ^

2)a*匹配1次,则i回退1位,j回退2位

s=“a a a” , i=1
   ^
p=“a a *” , j=1
   ^    

若“a”和“a”匹配,且“a”和“aa*”匹配,则“aa”和“aa*”匹配。
“a”和“a”匹配的条件为:s[i-1] == p[j-2] ,或p[j-2] == ‘.’(单个字符匹配)
“a”和“aa*”匹配的条件:有点抽象,因为a*可以匹配0到无数个a,因此要保证上一个状态是匹配的(j指向*,不动;i回退一位),当前状态才能匹配。上一个状态为:dp[i-1][j] = true
综上,a*匹配一次的条件:

dp[i-1][j] and (s[i-1] == p[j-2] or p[j-2] == '.')
1)和2)情况是并列的。

3)单个字符匹配:
两种,一种是相等匹配,另一种是‘.’匹配。而且上一个状态dp[i-1][j-1]匹配
条件:

dp[i-1][j-1] and (s[i-1] == p[j-1] or p[j-1] == '.')
此外还要注意下标,要保证i>0
因为有p[j-1] == ‘*’的限制,因此j不用过多限制
i从0到m
j从1到n,因为j=0时p为空串,除了空以外的所有s都不匹配

class Solution:
    def isMatch(self, s, p):
        """
        :type s: str
        :type p: str
        :rtype: bool
        """
        m,n = len(s), len(p)
        dp = [[False] * (n+1) for _ in range(m+1)]
        dp[0][0] = True
        for i in range(m+1):
            for j in range(1, n+1):
                if p[j-1] == '*':
                    dp[i][j] = dp[i][j-2] or (i>0 and dp[i-1][j] and (s[i-1] == p[j-2] or p[j-2] == '.'))
                else:
                    dp[i][j] = i>0 and dp[i-1][j-1] and (s[i-1] == p[j-1] or p[j-1] == '.')
        print(dp)
        return dp[m][n]
阅读更多

Pattern Matching Using Regular Expression

02-22

A regular expression is a string which contains some normal characters and some meta characters. The meta characters include,n. means any characternn[c1-c2] means any character between c1 and c2 (c1 and c2 are two characters)nn[^c1-c2] means any character not between c1 and c2 (c1 and c2 are two characters)nn* means the character before it can occur any timesnn+ means the character before it can occur any times but at least one timesnn\ means any character follow should be treated as normal characternYou are to write a program to find the leftmost substring of a given string, so that the substring can match a given regular expression. If there are many substrings of the given string can match the regular expression, and the left positions of these substrings are same, we prefer the longest one.nnnInputnnEvery two lines of the input is a pattern-matching problem. The first line is a regular expression, and the second line is the string to be matched. Any line will be no more than 80 character. A line with only an "end" will terminate the input.nnnOutputnnFor each matching problem, you should give an answer in one line. This line contains the string to be matched, but the leftmost substring that can match the regular expression should be bracketed. If no substring matches the regular expression, print the input string.nnnSample Inputnn.*nasdfnf.*d.nsefdfsden[0-9]+nasd345dsfn[^\*-\*]n**asdf**fasdnb[a-z]*r[s-u]*nabcdefghijklmnopqrstuvwxyzn[T-F]ndfkgjfnendnnnSample Outputnn(asdf)nse(fdfsde)nasd(345)dsfn**(a)sdf**fasdna(bcdefghijklmnopqrstu)vwxyzndfkgjf

没有更多推荐了,返回首页