给你一个字符串 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 <= 20
s
只包含从 a-z
的小写字母。p
只包含从 a-z
的小写字母,以及字符 .
和 *
。*
时,前面都匹配到有效的字符采用动态规划思想
建立dp[i][j]
表示s
的前i
项与p
的前j
项是否可以匹配
其中先初始化 dp 矩阵首行。dp[0][0] = true
: 代表两个空字符串能够匹配。当p[i] == '*'
时dp[0][i] = dp[0][i - 2]
当p[j]!=*
时
p[j]=='.'
,则此时无论如何s[i]
都可以与p[j]
匹配,所以此时dp[i][j]=dp[i-1][j-1]
'a'<=p[j]<='z'
,则此时只有s[i]==p[j]
时才可以匹配,所以此时dp[i][j]=dp[i-1][j-1]*(s[i]==p[j])
当p[j]==*
时,*
表示匹配零个或多个前面的那一个元素
dp[i][j]=dp[i][j-2]
*
前面为.
时,此时dp[i][j]=dp[i-1][j]
*
前面不为.
时,此时当且仅当p[j - 1] == s[i]
,即与*
的前一个想匹配时,dp[i][j]=dp[i-1][j]
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public:
bool isMatch(string s, string p) {
s = '0' + s;
p = '0' + p;
int dp[25][25];
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 1; i < p.length(); ++i) {
if (p[i] == '*') {
dp[0][i] = dp[0][i - 2];
}
}
// dp[i][j]对应s[:i+1],p[:j+1]是否匹配
for (int i = 1; i < s.length(); ++i) {
for (int j = 1; j < p.length(); ++j) {
if (p[j] != '*') {
if (p[j] == '.') {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = dp[i - 1][j - 1] * (s[i] == p[j]);
}
} else {
// *前个字母匹配0次,其中p中j:*,j-1:_*,j-2:__*
//dp[i][j] = dp[i][j - 2];
// 因为*可以匹配多个所以是p[j - 1] == s[i]
//*前一个字母为.
//if (p[j - 1] == '.' && dp[i][j] == 0) {
// dp[i][j] = dp[i - 1][j];
//}
//匹配*前一个字母
//if (p[j - 1] == s[i] && dp[i][j] == 0) {
// dp[i][j] = dp[i - 1][j];
//}
dp[i][j] = (dp[i - 1][j] && (p[j - 1] == '.' || p[j - 1] == s[i])) || dp[i][j - 2];
}
}
}
cout << endl;
cout << " ";
for (int i = 0; i < p.length(); ++i) {
cout << p[i] << " ";
}
cout << endl;
for (int i = 0; i < s.length(); ++i) {
cout << s[i] << " ";
for (int j = 0; j < p.length(); ++j) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
return dp[s.length() - 1][p.length() - 1];
}
};
//leetcode submit region end(Prohibit modification and deletion)
int main() {
Solution solution;
solution.isMatch("aab", "c*a*b");
}