请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
动态规划:
1、首先写出dp矩阵,定义dp矩阵中元素的意义,最好能够画图说明
2、列举矩阵中哥哥元素之间的关系,即状态转移方程,一般为dp[i][j]与dp[i-1][j],dp[i][j-1],dp[i-1][j-1]之间的关系。
3、定义矩阵的初始值。
public boolean isMatch(String s, String p) {
if(s==null || p==null) return false;
int sLen = s.length();
int pLen = p.length();
//dp[i][j]表示s中前i个字符[0,i-1]与p中的前j个字符[0,j-1]能否匹配
boolean[][] dp = new boolean[sLen+1][pLen+1];
dp[0][0] = true;//两个空字符可以相互匹配
for(int j = 1;j<dp[0].length;j++){
//在p中的第j-1位字符为*时,可以去掉p中的j-1与j-2位字符
//当dp[0][j-2]为true,也就是p中的[0,j-3]可以与s匹配时,可以将dp[0][j]置为true
if(p.charAt(j-1)=='*' && dp[0][j-2]){ //p不会出现第一个字符为*的情况,所以不会产生越界错误
dp[0][j] = true;
}
}
for(int i = 1;i<dp.length;i++){
for(int j = 1;j<dp[0].length;j++){
if(s.charAt(i-1) == p.charAt(j-1)){ //如果s[i-1]与p[j-1]相同
dp[i][j] = dp[i-1][j-1];
}else{ //如果s[i-1]与p[j-1]不相同
if(p.charAt(j-1)=='.'){ //.可以表示任意字符,所以.出现时认为当前位匹配
dp[i][j] = dp[i-1][j-1];
}else if(p.charAt(j-1)=='*'){
if(p.charAt(j-2)!=s.charAt(i-1)){ //p中*的前一位与s中当前位不匹配
//*可以p中的j-1与j-2位消失
dp[i][j] = dp[i][j-2];
}
if(p.charAt(j-2)==s.charAt(i-1) || p.charAt(j-2)=='.'){
//p中*的前一位与s当前位匹配,或者*的前一位为.
//当*表示取前面的0个字符时,s= aa,p = aab* 或p == aa.*,
//dp[i][j] = dp[i][j-2]
//取一个字符时,s=aab,p=aab*,此时p去掉一位 dp[i][j-1]
//取多位字符,s=aabb,p=aab*,相当于s去掉1位,s=aab与p==aab*进行匹配
//dp[i][j] = dp[i-1][j]
dp[i][j] = dp[i][j-2] || dp[i][j-1] || dp[i-1][j];
}
}else{//如果p[j-1]处是一个普通字符,p[j-1]无法与s[i-1]匹配
dp[i][j] = false;
}
}
}
}
return dp[sLen][pLen];
}
改进优化当p[j-1]字符为’*'的情况
当p[j-1]字符为*时,不管p[j-2]与s[i-1]是否相同,我们都可以将p[j-1]与p[j-2]去掉。
dp[i][j] = dp[i][j] || dp[i][j-2];
当p[j-1]字符为时,并且表示多个字符的情况,只有当p[j-2]==s[i-1]或者 '‘之前的符号为’.'时。
if(p.charAt(j-2)==s.charAt(i-1) || p.charAt(j-2)=='.'){
dp[i][j] = dp[i][j-1] || dp[i-1][j];
}
代码优化:
if(p.charAt(j-2)==s.charAt(i-1) || p.charAt(j-2)=='.'){
//取一个字符时,s=aab,p=aab*,此时p去掉一位 dp[i][j-1]
//取多位字符,s=aabb,p=aab*,相当于s去掉1位,s=aab与p==aab*进行匹配
//dp[i][j] = dp[i-1][j]
dp[i][j] = dp[i][j-1] || dp[i-1][j];
}
dp[i][j] = dp[i][j] || dp[i][j-2];
//不管p中*前一位是否与s的当前位相同,可以直接将p中*与*的前一位去掉
来源:CSDN
作者:是事可可
链接:https://blog.csdn.net/niqian6005/article/details/104571364