LintCode:192.通配符匹配(考点:动态规划)
程序员文章站
2022-03-24 17:38:02
...
题目:
分析:本题的考察点是动态规划。
字符串的模板匹配,实质上就是字符串之间的比较。但我们比较s[i]和p[j]是否能够匹配时,可以通过s[0,...,i-1]与p[0,...,j-1]的匹配关系来推导。如果我们已经知道s[0,...,i-1]和p[0,...,j-1]的匹配关系时,就可以很容易推导出s[0,...,i]和p[0,...,j]的匹配关系,其递推公式为:当p[j]为'*'时,由于'*'可以为0-n个任意字符,因此要考虑如下3种情况。
- 当p[j]为*时,由于*可以考虑为0~n个任意字符,因此分为3种不同的情况
(2)s[i-1]已经和p[j]进行了匹配,s[i]也仍然和p[j]进行匹配。此时考虑*表示n个字符。
(3)s[i]和p[j - 1]进行了匹配,此时考虑*表示0个字符。
- 当p[j]为?时,
s[i-1]和p[j-1]进行匹配,s[i]和p[j]进行匹配。
- 当p[j]为字母时,
s[i-1]和p[j-1]进行匹配,s[i]和p[j]进行匹配,看s[i-1]是否等于p[j-1]。
需要注意的是边界条件:
f[i][0] = false;f[0][0] = true;
但是对于f[0][j]需要特殊处理,当p[j]为*,f[0][j]的值可以等于f[0][j-1],此时将*考虑为0个字符。
最后根据f[s.size()][p.size()]的值就可以判定s和p是否能够匹配。
package String;
public class isMatch {
/**
* @param s: A string
* @param p: A string includes "?" and "*"
* @return: is Match?
*/
//通配符匹配
//判断两个可能包含通配符“?”和“*”的字符串是否匹配。匹配规则如下:
// '?' 可以匹配任何单个字符。
// '*' 可以匹配任意字符串(包括空字符串)。
//两个串完全匹配才算匹配成功。
//采用动态规划思想
public boolean isMatch(String s, String p) {
// write your code here
if(s==null || p==null) return false;
int m=s.length();
int n=p.length();
boolean[][] f=new boolean[m+1][n+1];
f[0][0]=true;
for(int i=1;i<=m;i++)
f[i][0]=false;
for(int i=1;i<=n;i++)
f[0][i]=(f[0][i-1] && p.charAt(i-1)=='*'); //当p[j]为*,f[0][j]的值可以等于f[0][j-1],此时将*考虑为0个字符
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(p.charAt(j-1)=='*'){
f[i][j]=f[i-1][j-1] || f[i-1][j] || f[i][j-1];
}else if(p.charAt(j-1)=='?'){
f[i][j]=f[i-1][j-1];
}else{
f[i][j]=f[i-1][j-1] && s.charAt(i-1)==p.charAt(j-1);
}
}
}
return f[m][n];
}
}