给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。 p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
动态规划
dp[i][j] 保存s的前i个字符和p的前j个字符是否匹配
public boolean isMatch(String s, String p) {
if(s == null || p == null) return false; // 是==null不是len=0
int m = s.length();
int n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;
//a*a*a*a* 初始化 重点!!
for(int i = 2; i <= n; i+=2){
if(p.charAt(i-1) == '*'){
dp[0][i] = dp[0][i-2];
}
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'){ //当前可以匹配成功
dp[i+1][j+1] = dp[i][j];
}
if(p.charAt(j) == '*'){ //当前字符为*
if(p.charAt(j-1) != s.charAt(i) && p.charAt(j-1) != '.'){ //考虑上一个字符p[j-1]不为'.' 且上一个字符与s[i]不同的情况
dp[i+1][j+1] = dp[i+1][j-1]; //P退两个字符,相当于去掉'm*'
}
else{ //重点!!!
dp[i+1][j+1] = (dp[i][j+1] || dp[i+1][j] || dp[i+1][j-1]); //考虑上一个字符p[j-1]为.的情况 或者s[i] == p[j-1]时
//dp[i][j+1] m*可匹配多次 mmmmm -- m* >1
//dp[i+1][j] m*可匹配一次 m* --- m* ==1
//dp[i+1][j-1] m*不匹配 ==0
}
}
}
}
return dp[m][n];
}