LeetCode-Wildcard Matching

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

算法来自http://blog.unieagle.net/2012/11/07/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Awildcard-matching/

使用贪心法,首先按*将p串分割成各个不含*的子串,对于串头无*的子串必须从字符串头匹配,串尾无*的子串必须从字符串尾开始匹配,其他子串按顺序匹配即可

class Solution {
public:
    vector<string> GenPattern(const char* p,bool& first,bool&last){
        vector<string> ret;
        if(p[0]=='\0')return ret;
        string s="";
        int i=0;
        if(p[0]!='*')first=true;
        while(p[i]!='\0'){
            if(p[i]=='*'){
                if(s!="")ret.push_back(s);
                s.clear();
            }
            else{
                s+=p[i];
            }
            i++;
            if(p[i]=='\0'){
                if(p[i-1]!='*'){
                    last=true;
                    ret.push_back(s);
                }
            }
        }
        return ret;
    }
    bool allStar(const char* p){
        int i=0;
        if(p[0]=='\0')return false;
        while(p[i]!='\0'){
            if(p[i]!='*')return false;
            i++;
        }
        return true;
    }
    int kmpSearch(string& s,string& p,int start){
        vector<int>next;
        next.resize(p.length());
        if(p.length()==1){
            for(int i=start;i<s.length();i++)if(s[i]==p[0]||p[0]=='?')return i+1;
            return -1;
        }
        next[0]=-1;
        next[1]=0;
        for(int i=2;i<p.length();i++){
            int j=next[i-1];
            while(j>=0&&p[j]!=p[i-1]&&p[j]!='?'&&p[i-1]!='?'){
                j=next[j];
            }
            j++;
            next[i]=j;
        }
        int ptr=0,i=start;
        while(true){
            if(s[i]==p[ptr]||p[ptr]=='?'){
                ptr++;
                i++;
                if(ptr==p.length()){
                    return i;
                }
                if(i>=s.length())break;
            }
            else{
                while(ptr>=0&&s[i]!=p[ptr]&&p[ptr]!='?'){
                    ptr=next[ptr];
                }
                ptr++;
                i++;
                if(i>=s.length())break;
            }
        }
        return -1;
    }
    bool isMatch(const char *s, const char *p) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        bool first=false,last=false;
        if(allStar(p))return true;
        vector<string> ps=GenPattern(p,first,last);
        string ss(s);
        if(ps.size()==0){
            if(ss.length()==0)return true;
            else return false;
        }
        if(ps.size()==1){
            
            if(first&&last){
                if(ss.length()!=ps[0].length())return false;
                for(int i=0;i<ss.length();i++){
                    if(ss[i]!=ps[0][i]&&ps[0][i]!='?')return false;
                }
            }
            else if(first||last){
                int k=0;
                if(first){
                    int j=0;
                    for(int i=0;i<ps[0].length();i++){
                        if(j==ss.length())return false;
                        if(ss[j]!=ps[k][i]&&ps[k][i]!='?')return false;
                        j++;
                    }
                }
                if(last){
                    int i=ss.length()-1;
                    for(int j=ps[k].length()-1;j>=0;j--){
                        if(i<0)return false;
                        if(ss[i]!=ps[k][j]&&ps[k][j]!='?')return false;
                        i--;
                    }
                }
            }
            else{
                if(kmpSearch(ss,ps[0],0)<0)return false;
            }
            return true;
        }
        int k=0;
        int end=0;
        if(first){
            int j=0;
            for(int i=0;i<ps[0].length();i++){
                if(j==ss.length())return false;
                if(ss[j]!=ps[k][i]&&ps[k][i]!='?')return false;
                j++;
            }
            k++;
            end=ps[0].length();
        }
        
        for(;k<ps.size()-1;k++){
            end=kmpSearch(ss,ps[k],end);
            if(end==-1)return false;
        }
        if(last){
            int i=ss.length()-1;
            for(int j=ps[k].length()-1;j>=0;j--){
                if(i<end)return false;
                if(ss[i]!=ps[k][j]&&ps[k][j]!='?')return false;
                i--;
            }
        }
        else{
            end=kmpSearch(ss,ps[k],end);
            if(end==-1)return false;
        }
        return true;
    }
};
View Code

 

posted @ 2013-10-08 20:28  懒猫欣  阅读(334)  评论(0)    收藏  举报