10.正则表达式匹配
一、题目内容
给你一个字符串 s
和一个字符规律 p
,请你来实现一个支持 '.'
和 '*'
的正则表达式匹配。
'.'
匹配任意单个字符'*'
匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s
的,而不是部分字符串。
示例 1
输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。
示例 2
输入:s = "aa", p = "a*"
输出:true
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3
输入:s = "ab", p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。
提示
1 <= s.length <= 20
1 <= p.length <= 30
s
只包含从a-z
的小写字母。p
只包含从a-z
的小写字母,以及字符.
和*
。- 保证每次出现字符
*
时,前面都匹配到有效的字符
二、分析题目
动态规划方法解题
针对问题考虑采用动态规划方法解题,采用DP二维布尔值数组进行讨论。针对该问题需要讨论不同情况的特殊情况下面取以下几个例子,满足以上几个例子即可完成所有。
情况一
s和p对应字符串表
S | a | a |
---|---|---|
P | a |
DP数组对应表
0 | 1 | 3 | |
---|---|---|---|
0 | TRUE | | FALSE a| | FALSE aa| |
1 | FALSE |a | TRUE a|a | FALSE aa|a |
情况二
s和p对应字符串
S | a | a |
---|---|---|
P | a | * |
DP数组对应表
0 | 1 | 2 | |
---|---|---|---|
0 | TRUE | | FALSE a| | FALSE aa| |
1 | FALSE |a | TRUE a|a | FALSE aa|a |
2 | TRUE |a* | TRUE a|a* | TRUE aa|a* |
情况三
s和p,对应的字符串
S | a | a |
---|---|---|
P | . | * |
DP数组对应表
0 | 1 | 2 | |
---|---|---|---|
0 | TRUE | | FALSE a| | FALSE aa| |
1 | FALSE |. | TRUE a|. | FALSE aa|. |
2 | TRUE |.* | TRUE a|.* | TRUE aa|.* |
情况四
在这种情况需要考虑.二者出现时,根据性质,删除.**的情况。
s和p,对应的字符串:
S | a | b | ||
---|---|---|---|---|
P | a | . | * | b |
DP数组对应表
0 | 1 | 2 | |
---|---|---|---|
0 | TRUE | | FALSE a| | FALSE ab| |
1 | FALSE |a | TRUE a|a | FALSE ab|a |
2 | FALSE |a. | FALSE a|a. | TRUE ab|a. |
3 | FALSE |a.* | TRUE a|a.* | TRUE ab|a.* |
4 | FALSE |a.*b | FALSE a|a.*b | TRUE ab|a.*b |
综合总结状态转移方程如下
$$
dp[i][j] =
\begin{cases}
dp[i-1][j-1],& s[i-1] = p[j-1] \space or \space p[j-1]=''\
dp[i-1][j]\space or \space dp[i][j-2], & p[j-1] ='' \space and \space (s[i-1]=p[j-2]\space or \space p[j-2]='.') \
dp[i][j-2],& p[j-1] ='*' \space and \space not \space (s[i-1]=p[j-2]\space or \space p[j-2]='.')\
\end{cases}
\s.t. i>0, j>0
$$
三、代码
public boolean isMatch(String s, String p) {
// 转为字符串数组 AS AP
char[] AS = s.toCharArray(), AP = p.toCharArray();
// dp[i][j] boolean组 默认值为false
boolean[][] dp = new boolean[AS.length + 1][AP.length + 1];
dp[0][0] = true;
// 初始化 j=0 的dp
for (int i=1; i<=AP.length; i++){
if (AP[i-1] == '*')
dp[0][i] = dp[0][i-2];
}
for (int i=1; i<=AS.length; i++){
for (int j=1; j<=AP.length; j++){
if (AS[i-1] == AP[j-1] || AP[j-1] == '.'){
dp[i][j] = dp[i-1][j-1];
}else if(AP[j-1] == '*'){
if (AP[j-2] == AS[i-1] || AP[j-2] == '.'){
// 保留或舍去
dp[i][j] = dp[i-1][j] || dp[i][j-2];
}else{
dp[i][j] = dp[i][j-2];
}
}
}
}
return dp[AS.length][AP.length];
}
标签:aa,10,匹配,space,正则表达式,字符串,FALSE,TRUE,dp
From: https://www.cnblogs.com/vvvigo/p/16907078.html