

求解代码
java
public boolean match (String str, String pattern) {
int m = str.length();
int n = pattern.length();
boolean[][] dp = new boolean[m+1][n+1];
for(int i=0;i0&&(str.charAt(i-1)==pattern.charAt(j-1)||pattern.charAt(j-1)=='.')){
dp[i][j]=dp[i-1][j-1];
}
}else{
if(j>=2){
dp[i][j]|=dp[i][j-2];
}
if(i>=1&&j>=2&&(str.charAt(i-1)==pattern.charAt(j-2)||pattern.charAt(j-2)=='.')){
dp[i][j]|=dp[i-1][j];
}
}
}
}
}
return dp[m][n];
}
小贴士
DP这个boolean数组,dp[i][j]的意思是str的前i个字符和pattern的前j个字符,能否匹配成功。
这里的DP数组,考虑了下标0位置的空字符串,所以为了存储整个字符串,DP数组长度需要+1。
这里没有像编辑距离那题一样单独处理初始化逻辑,而是在嵌套for循环的逻辑中处理的,这样代码会更简洁一些。
这里有个细节需要注意一下就是,dp[i][j]是前 i/j个字符,所以pattern的第 j个字符对应原字符串的下标为j-1的字符,其实和【编辑距离】的下标转换是一样的。
当pattern非空的时候,大范围是考虑了pattern[j-1]是否为*两种情况。
1.当pattern[j-1]不是*时,如果str非空并且和str[j-1]相对或者pattern[j-1]直接是.的话,说明匹配成功。
2.当pattern[j-1]是*的话,就需要考虑是零次匹配前面的字符 还是匹配多次前面的字符的问题了。
因为pattern[j-1]是*,所以pattern[j-2]就是*的前驱字符,那处理这类情况就应该着重看看pattern[j-2]了。
-
如果是匹配
0次前驱字符,那pattern的j-2和j-1位都可以舍弃,此时要判断str前i个和pattern前j个是否匹配,等价于判断str前i个和pattern前j-2个是否匹配。 -
如果是匹配了多次前驱字符,那就让
pattern保持不动,让str的前i-1个字符和pattern的前j个字符继续匹配。