题目描述
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
python实现:
# -*- coding:utf-8 -*-
class Solution:
# s, pattern都是字符串
# 法1:直接匹配,使用递归
def match2(self , str , pattern ):
# write code here
m, n = len(str), len(pattern)
if m==0 and n==0:
return True
if m>0 and n==0:
return False
# 到这里了,n肯定>0
if n>1 and pattern[1]=="*":
if m>0 and (str[0]==pattern[0] or pattern[0]=='.'):
# # *表示0次,# *表示1次,# * 表示多次
return self.match(str[:], pattern[2:]) or \
self.match(str[1:], pattern[2:]) or \
self.match(str[1:], pattern[:]) # * 表示多次
else:
# * 必须表示0次,直接忽略掉a*
return self.match(str[:], pattern[2:])
elif m>0 and (str[0]==pattern[0] or pattern[0]=='.'):
return self.match(str[1:], pattern[1:])
return False
# 法1:的另一种写法
def match3(self , str , pattern ):
m, n = len(str), len(pattern)
if m==0 and n==0:
return True
if m>0 and n==0:
return False
# 到这里了,n肯定>0
return self.is_match(str, 0, pattern, 0)
def is_match(self, s, sstart, p, pstart):
if sstart == len(s) and pstart == len(p):
return True
if sstart<len(s) and pstart==len(p):
return False
# 到这里了,pstart肯定<len(p)
if pstart+1<len(p) and p[pstart+1]=="*":
if sstart<len(s) and (s[sstart]==p[pstart] or p[pstart]=='.'):
return self.is_match(s, sstart, p, pstart+2) or \
self.is_match(s, sstart+1, p, pstart+2) or \
self.is_match(s, sstart+1, p, pstart)
else:
# * 只能表示0次,直接忽略a*
return self.is_match(s, sstart, p, pstart+2)
elif sstart<len(s) and (s[sstart]==p[pstart] or p[pstart]=='.'):
return self.is_match(s, sstart+1, p, pstart+1)
return False
#法2:动态规划
# 分析:设dp[i][j]表示s(0,i)与p(0,j)的匹配情况,True表示匹配,False表示不匹配,则dp[0][0]=True
# 当p[j]=='*'时,dp[i][j] = dp[i][j-2] or dp[i][j-1] or (s[i]==p[j-1] or p[j-1]=='.') and dp[i-1][j]
# 当p[j]=='.'或p[j]==s[i]时,dp[i][j]=dp[i-1][j-1]
def match(self, s, pattern):
m, n = len(s), len(pattern)
if m==0 and n==0:
return True
dp = [ [False]*(n+1) for _ in range(m+1)]
#初始化
dp[0][0] = True
for j in range(1, n+1):
if j>1 and pattern[j-1]=="*":
dp[0][j] = dp[0][j-2]
for i in range(1, m+1):
for j in range(1, n+1):
if pattern[j-1]=="." or pattern[j-1]==s[i-1]:
dp[i][j] = dp[i-1][j-1]
elif pattern[j-1]=="*":
dp[i][j] = dp[i][j-2] or dp[i][j-1] or dp[i-1][j] and (s[i-1]==pattern[j-2] or pattern[j-2]==".")
return dp[m][n]