欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-24 17:38:02
...

题目:

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