44. Wildcard Matching

来源:互联网 发布:怡海软件技术有限公司 编辑:程序博客网 时间:2024/05/17 01:48

题目: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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "*") → trueisMatch("aa", "a*") → trueisMatch("ab", "?*") → trueisMatch("aab", "c*a*b") → false

解法一:

这题想法参考了https://oj.leetcode.com/discuss/10133/linear-runtime-and-constant-space-solution,

类似于一种有限状态机的做法。

主要思想如下:

由于*匹配多少个字符是不一定的,于是首先假设*不匹配任何字符。

当后续匹配过程中出错,采用回溯的方法,假设*匹配0个字符、1个字符、2个字符……i个字符,然后继续匹配。

因此s需要有一个spos指针,记录当p中的*匹配i个字符后,s的重新开始位置。

p也需要一个starpos指针指向*的位置,当回溯过后重新开始时,从starpos的下一位开始。

代码:

bool isMatch(char* s, char* p) {            char* starpos = NULL;        char* spos = NULL;                while(true)        {            if(*s == 0 && *p == 0)            //match all                return true;            else if(*s == 0 && *p != 0)            {//successive *p must be all '*'                while(*p != 0)                {                    if(*p != '*')                        return false;                    p ++;                }                return true;            }            else if(*s != 0 && *p == 0)            {                if(starpos != NULL)                {//maybe '*' matches too few chars in s                    p = starpos + 1;                    s = spos + 1;                    spos ++;    //let '*' matches one more chars in s                }                else                //*s is too long                    return false;            }            else            {                if(*p == '?' || *s == *p)                {                    s ++;                    p ++;                }                else if(*p == '*')                {                    starpos = (char*)p;                    spos = (char*)s;                    p ++;                       //start successive matching from "'*' matches non"                }                //currently not match                else if(starpos != NULL)                {//maybe '*' matches too few chars in s                    p = starpos + 1;                    s = spos + 1;                    spos ++;    //let '*' matches one more chars in s                }                else                //not match                    return false;            }        }        }

更加简洁的办法:

bool isMatch(char* s, char* p) {        char* star=NULL;        char* ss=s;        while (*s){            //advancing both pointers when (both characters match) or ('?' found in pattern)            //note that *p will not advance beyond its length             if ((*p=='?')||(*p==*s)){s++;p++;continue;}             // * found in pattern, track index of *, only advancing pattern pointer             if (*p=='*'){star=p++; ss=s;continue;}             //current characters didn't match, last pattern pointer was *, current pattern pointer is not *            //only advancing pattern pointer            if (star){ p = star+1; s=++ss;continue;}            //current pattern pointer is not star, last patter pointer was not *           //characters do not match            return false;        }       //check for remaining characters in pattern        while (*p=='*'){p++;}        return !*p;  }



解法二:

按照Regular Expression Matching  的做法,但是当*很多的时候,就会超时 Time Limit Exceeded 

代码:

bool isMatch(char* s, char* p) {    if(strlen(s)==0 && strlen(p)==0) return true;        //*匹配任何的字符串,包括空串    if(strlen(p)==1 && p[0]=='*') return true;    if(p[0] != '*')    {        if(*s == '\0')        {            return false;        }        else        {            if(s[0]!=p[0] && p[0] !='?')            {                return false;            }            else            {                return isMatch(s+1, p+1);            }        }    }        while(s[0]!='\0'  )    {        if(isMatch(s,p+1)) return true;        else s++;    }        while('*'== p[0])        p++;        return '\0'==p[0];}

解法三:

































0 0