题目:
分析:本题的考察点是动态规划。
字符串的模板匹配,实质上就是字符串之间的比较。但我们比较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]; } }