这个比较困难,我参考了网上的代码: https://leetcode-cn.com/problems/regular-expression-matching/solution/di-gui-dong-tai-gui-hua-zhu-xing-jie-shi-python3-b/
思路: 动态规划, 沿着匹配串和字符串构成矩阵的对角线传递状态
1. 状态矩阵的首行与首列对应于空字符与空匹配符
2. 对角线意味着匹配串是否匹配对应的字符串
具体代码以下:
'''
p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1]
If p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
If p.charAt(j) == '*': here are two sub conditions:
//in this case, a* only counts as empty, otherwise is not match
- if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2]
- if p.charAt(j-1) == s.charAt(i) or p.charAt(i-1) == '.':
dp[i][j] = dp[i-1][j] //in this case, a* counts as multiple a
dp[i][j] = dp[i][j-1] // in this case, a* counts as single a
dp[i][j] = dp[i][j-2] // in this case, a* counts as empty
'''
def isMatch(s, p):
ls=len(s) #length of s
lp=len(p) #length of p
#定义dp空间
dp=[[False]*(lp+1) for _ in range(ls+1)]
dp[0][0]=True
#初始化首行
for i in range(lp):
if p[i]=='*' and dp[0][i-1]:
dp[0][i+1]=True
#更新状态dp
for i in range(1,ls+1): #dp指针,从1开始
for j in range(1,lp+1): #0地址已经初始化为True
m=i-1 #s指针,从0开始
n=j-1 #p指针
if s[m]==p[n]: #如果字符匹配
dp[i][j]=dp[i-1][j-1] #获取前一dp状态
elif p[n]=='.': #.肯定能匹配字符
dp[i][j]=dp[i-1][j-1] #获取前一dp状态
elif p[n]=='*': #处理字符为*,*表示n-1的延续
if s[m]==p[n-1] or p[n-1]=='.': #
dp[i][j]=dp[i-1][j] or dp[i][j-1] or dp[i][j-2]
elif s[m]!=p[n-1]: #字符不等于*的前位字符
dp[i][j]=dp[i][j-2] #获取前二位dp状态
return dp[ls][lp]
s=['ab','aaabc','ab']
p=['abc*','a*bc','.*']
print(isMatch(s[2],p[2]))
来源:oschina
链接:https://my.oschina.net/tedzheng/blog/3167454