LeetCode题解:Wildcard Matching

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

思路:

应该可以用动态规划的方法来处理。

题解:

class Solution {
public:
    bool isMatch (const char* s, const char* p)
    {
        if (s == 0 || p == 0) return false;
        
        while (true)
        {
            if (*s == 0 && *p == 0) return true;
            
            if (*p == 0) return false;
            
            if (*p == '?' || *p == *s)
            {
                ++s, ++p;
            }
            else if (*p == '*')
            {
                const char* next_p = p + 1;
                while (*next_p == '*' && *next_p != 0) ++next_p;
                
                if (*s == 0)
                    return *next_p == 0;
                else
                {
                    if (*next_p == '?')                                                                    
                        return isMatch (s, next_p) || isMatch (s + 1, p);                                  
                    else if (*next_p != 0)                                                                 
                    {                                                                                      
                        const char* next_s = s;                                                            
                        bool valid = false;                                                                
                        while (*next_s != 0)                                                               
                        {                                                                                  
                            if (*next_s == *next_p && isMatch (next_s + 1, next_p + 1))                    
                            {                                                                              
                                valid = true;                                                              
                                break;                                                                     
                            }
                            ++next_s;
                        }
                        return valid;
                    }
                    else
                        return true;
                }
            }
            else
                return false;
        }
    }
};
思路:

上述方法是超时的。没有办法。不过考虑到其实可以把pattern以*为间隔分块,然后在字符串里看是否这些块按顺序出现,当然开头和结尾的部分要特殊处理一下。比如结尾的块不是'*',那么就必须按照倒序检查原始字符串末尾的字符。

题解:

class Solution {
public:
#define charMatch(s, p) (p == '?' || p == s)
    int subStr (const char* s, int start, const char* p, int len)
    {
        while (s[start] != 0)
        {
            if (charMatch (s[start], p[0]))
            {
                bool match = true;
                for (int j = 1; j < len; ++j)
                    if (s[start + j] == 0)
                        return -1;
                    else if (!charMatch (s[start + j], p[j]))
                    {
                        match = false;
                        break;
                    }
                    
                if (match)                                                                                 
                    return start + len;                                                                    
            }                                                                                              
                                                                                                           
            ++start;                                                                                       
        }                                                                                                  
        return -1;                                                                                         
    }                                                                                                      
#undef charMatch                                                                                       
                                                                                                           
    bool isMatch (const char* s, const char* p)                                                            
    {                                                                                                      
        bool front_vary = *p == '*';                                                                       
        bool back_vary = false;
        
        int s_offset = 0;
        int p_start = 0;
        int p_offset = 0;
        while (p[p_offset] != 0)
        {
            p_start = p_offset;
            while (p[p_start] == '*' && p[p_start] != 0) ++p_start;
            
            if (p[p_start] == 0)
            {
                // is pattern empty?
                if (p_start != 0)
                    back_vary = p[p_start - 1] == '*';
                break;
            }
            
            p_offset = p_start + 1;
            while (p[p_offset] != '*' && p[p_offset] != 0) ++p_offset;
            
            if (p[p_offset] == 0 && p_start != 0)
            {
                // for the last block we need to do matching backwards
                int old_soffset = s_offset;
                while (s[s_offset] != 0) ++s_offset;
    
                int pi = p_offset;
                int si = s_offset;
                while(pi >= p_start && si >= old_soffset)
                {
                    if (p[pi] != '?' && p[pi] != s[si])
                        return false;
                    --pi, --si;
                }
    
                if (pi >= p_start)
                    return false;   // s does not have enough space
            }
            else
            {
                s_offset = subStr (s, s_offset, p + p_start, p_offset - p_start);
                
                if (s_offset == -1 || (p_start == 0 && !front_vary && s_offset != p_offset - p_start))
                    return false;
            }
        }
        
        if (!back_vary && s[s_offset] != 0)
            return false;
        else
            return true;
    }
};


你可能感兴趣的:(LeetCode)