LintCode:192.通配符匹配(考点:动态规划)

题目:


分析:本题的考察点是动态规划

           字符串的模板匹配,实质上就是字符串之间的比较。但我们比较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种不同的情况
     (1)s[i-1]和p[j-1]进行匹配,s[i]和p[j]进行匹配。此时考虑*表示1个字符。

     (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()]的值就可以判定sp是否能够匹配。

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];
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27139155/article/details/80094880
今日推荐