正则表达式

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.‘ 和 ‘*‘ 的正则表达式匹配。

‘.‘ 匹配任意单个字符
‘*‘ 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

  • s 可能为空,且只包含从 a-z 的小写字母。
  • p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *

示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

示例 2:

输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 ‘*‘ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a‘。因此,字符串 "aa" 可被视为 ‘a‘ 重复了一次。

示例 3:

输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个(‘*‘)任意字符(‘.‘)。

示例 4:

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 ‘*‘ 表示零个或多个,这里 ‘c‘ 为 0 个, ‘a‘ 被重复一次。因此可以匹配字符串 "aab"。

示例 5:

输入:
s = "mississippi"
p = "mis*is*p*."
输出: false--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------解答:这个题规则有点儿多,需要先理清思路:问题一,用递归应该怎么递归?1.应为题目给的字符串有S和P其中S中全是普通字符串,P作为匹配字符串里面有特殊字符。2.按照P中出现的字符串是不是*好分类,并分别写出递归式:  1)不是*号(是普通字符)  此时比较简单  dp[i][j] = dp[i-1][j-1] s[i-1]==p[j-1];   dp[i][j] = false s[i-1]!=p[j-1];     解释:因为当前出现的是普通字符,那么它与当前这个字符能不能匹配的必要条件是s[i]==p[j], 如果这个条件不满足那么一定匹配不上,满足后还要看前一个是不是能匹配上,前一个能匹配上       那么一定是可以的,如果前一个没匹配上那一定不行。  2)是*号  这个时候要复杂点儿。首先考虑到*号的用途有*好的所有情况分类。       1)一定要将前一个抵消才可能满足。意思就是将前一个给废了才可能满足,这个时候是什么情况呢?  这个时候就是p[j-2]!=s[i-1]这样*好智能不代表前面一个才有可能,此时的动态规划式是:        dp[i][j] = dp[i][j-2]   p[j-2]!=s[i-1];    2)不将*号的前一个给废了也可能匹配到所有的字符。        dp[i][j] = dp[i][j-2] or dp[i][j-1] or dp[i-1][j]   p[j-2]!=s[i-1]; 分别对应将前一个销毁,一个前一个,两个以上前一个。 这个逻辑不是很完备,因为这里仅仅只     考虑到满足情况的时候一定是对的,但是当不满足情况时会不会被误判为对呢?  只能说有可能,但是分析起来异常困难,这里就不做分析,到时候出了问题再来调。
  3)边界条件,按照以上两点分类,在一般的情况下是全部都分类完了,不存在分类的不完全和交叉。。但是没有考虑边界情况    1)对1)中,如果s或者p中是第一个元素怎么办,这时候前面一个元素是没有的。        这时候需要考察一下这个空的意义,空就是所有的匹配到那儿啥也没有了,比如s为空   p为空  那肯定能匹上。   S为空p不为空,那证明p中全部都该消失,形如:a*b*.啥也没有。      按照以上逻辑就能解决这个问题。    2)对2) 中,如果j-2<0 or j-1<0 or i-1<0 呢?  这个其实很简单 : 思路就是 : 既然不存在  那就不称其为证据。也就是false.总结:考虑每种情况的实际意义,在这个意义下再来同一安排,只要是在同一的意义下,且每个值都是对的,那么在这个意义下递推公式得到的结果就是对的。以上就应该考虑空对应的意义。要不然就只有反复补漏就很烦。