17 July 2014

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

解法:这题与之前那题类似,区别是这题搜索量更大,用递归会TLE。AC的是贪心的代码,抄的这篇文章。难处就是处理*的情况,这里用的方法是,遍历S,与P,尽量匹配(匹配P中越多字符越好),记录不匹配时是否可以回溯,两个游标分别该回溯到哪个位置。

  1. abcdcdcdaa*cdcda比较。
  2. abcdcd c daa*cdcd a 不匹配时,S串应该回溯到abc d cdcda,P串应该回溯到a* c dcda
  3. 继续比较还是不匹配,S串应该回溯到abcd c dcda,P串应该回溯到a* c dcda
  4. P一直回溯到原来位置,因为P中字符总是要被全部匹配的。

代码如下:贪心

//{java}
public class Solution {
    public boolean isMatch(String s, String p) {
        int bs=-1,bp=-1;
        int is=0,ip=0;
        while(is<s.length())
        {
            if(ip<p.length() && (s.charAt(is)==p.charAt(ip) || p.charAt(ip)=='?') )
            {
                is++;
                ip++;
            }else
            {
                if(ip<p.length()&&p.charAt(ip)=='*')
                {
                    while(ip<p.length() && p.charAt(ip)=='*')
                        ip++;
                    bp=ip;
                    bs=is;
                }else
                {
                    if(bp==-1)
                        return false;
                    else
                    {
                        is=++bs;
                        ip=bp;
                    }
                }
            }
        }
        while(ip<p.length() && p.charAt(ip)=='*')
                    ip++;
        return is==s.length() && ip==p.length();
    } 
}

递归代码,会超时:

//{java}
public class Solution {
    public boolean isMatch(String s, String p) {
        int sl = s.length();int pl=p.length();
        if(pl==0)
            return sl==0;
        if(p.charAt(0)!='?' && p.charAt(0)!='*')
            return sl>0&&p.charAt(0)==s.charAt(0) && isMatch(s.substring(1,sl),p.substring(1,pl));
        if(p.charAt(0)=='?')
            return sl>0&&isMatch(s.substring(1,sl),p.substring(1,pl));
        if(p.charAt(0)=='*')
        {
            if(sl>0&&isMatch(s.substring(1,sl),p))
                return true;
        }
        return isMatch(s,p.substring(1,pl));
        
    }
}


blog comments powered by Disqus