题目描述
请实现一个函数用来匹配包括’.’和’*‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab\ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配
解答
待补充
网上题解
链接:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c?answerType=1&f=discussion
来源:牛客网
方法一:递归
假设主串为s,长度为sn
, 模式串为p
,长度为pn
,对于模式串p当前的第i
位来说,有'正常字符'、'*'、'.'
三种情况。我们针对这三种情况进行讨论:
- 如果
p[i]
为正常字符, 那么我们看s[i]
是否等于p[i]
, 如果相等,说明第i位匹配成功,接下来看s[i+1...sn-1] 和 p[i+1...pn-1]
- 如果p[i] 为
'.'
, 它能匹配任意字符,直接看s[i+1...sn-1] 和 p[i+1...pn-1]
- 如果
p[i]
为'*'
, 表明p[i-1]
可以重复0
次或者多次,需要把p[i-1] 和 p[i]
看成一个整体.- 如果
p[i-1]
重复0
次,则直接看s[i...sn-1] 和 p[i+2...pn-1]
- 如果
p[i-1]
重复一次或者多次,则直接看s[i+1...sn-1] 和p[i...pn-1]
,但是有个前提:s[i]==p[i] 或者 p[i] == '.'
- 如果
三种情况如下图:
显然上述的过程可以递归进行计算。
则递归三部曲为:
- 递归函数功能:
match(s, p) -> bool
, 表示p
是否可以匹配s - 递归终止条件:
- 如果
s 和 p
同时为空,表明正确匹配 - 如果
s不为空,p为空
,表明,不能正确匹配 - 如果
s为空,p不为空
,需要计算,不能直接给出结果
- 如果
- 下一步递归:
- 对于前面讨论的情况
1,2
进行合并,如果*s == *p || *p == '.',则match(s+1, p+1)
- 对于情况
3
,如果重复一次或者多次,则match(s+1,p),如果重复0次,则match(s, p+2)
- 对于前面讨论的情况
具体代码如下:
1 | class Solution { |
方法二:动态规划
方法一的递归代码属于自顶向下,而动态规划的代码属于自底向上。
- 动态规划转移方程:
f[i][j]
表示s
的前i
个和p
的前j
个能否匹配
对于方法一种的
1,2
两种情况可知:f[i][j] = f[i-1][j-1]
对于第
1
3
种情况可知:
- 如果重复
0
次,f[i][j] = f[i][j-2]
- 如果重复
1
次或者多次,f[i][j] = f[i-1][j]
- 如果重复
- 动态规划初始条件:
s为空且p为空,为真: f[0][0] = 1
s不为空且p为空,为假: f[1..sn][0] = 0
代码如下:
1 | class Solution { |