leetcode 10|44. Regular Expression Matching 44. Wildcard Matching

10. Regular Expression Matching

Implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.
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", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

关键在于 .* 的处理

分情况挨个匹配


class Solution {
public:
    bool isMatch(string s, string p)
    {
        if (s == "")
        {
            if (p == "")
                return true;
            else if (p.size() > 1 && p[1] == '*')
                return  isMatch(s, p.substr(2));
            else
                return false;
        }
        else if (p == "")
            return false;
        
        if (p.size() == 1)//当p只有一位
        {
            if (s.size() > 1)
                return false;
            else
                return (p[0] == s[0] || p[0] == '.');
        }
        
        if (p[1] != '*') //p大于等于2位,第二位不是*
        {
            if (p[0] == '.' || p[0] == s[0])
                return isMatch(s.substr(1), p.substr(1));
            else
                return false;
        }
        else //第二位是*
        {
            if (p[0] != s[0] && p[0] != '.')    //前两位匹配不上
                return isMatch(s, p.substr(2, p.size() - 2));
            else //前两位能匹配上
            {
                if (isMatch(s, p.substr(2)))    //虽然前两位能匹配上,但也可以舍去
                    return true;
                
                int i = 0;
                while (s[i] == p[0] || p[0] == '.')
                {
                    if (isMatch(s.substr(i + 1), p.substr(2)))  //p的前两位 能 匹配s的多少位 情况都 算一下
                        return true;
                    if (s.substr(i + 1) == "")
                        break;
                    i++;
                }
                return false;
            }
        }
        return false;
    }
};


44. 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

因为p中的*可以匹配s中的0个或一个或多个,到底匹配几个呢?这取决于*的下一位。
比如看 s = abbb;      p = a*b 这个例子。s0 = p0= a, p1=*, 那么*到底匹配几个b呢?看*后的p2 = b, 因为p2如果和s3=b匹配了,那么可以用*去匹配s1~s2,即bb,这样就完成了匹配。如果*匹配s的方式为其它方式,那么都没法得出s和p匹配。
这说明,这道题目的关键就是在遇到p中的*之后,检验每一种可p中的*和s中的字符的匹配方式。
为了实现这一点,在出现*时,需要保留此时的*的位置和s中的对应位置。
可以对照代码看看下面几个例子,体会*的用途。
 s = "aab"        p = "a*a*b"; // true
 s = "abbb";      p = "a*b"; //true
 s = "abb";       p = "a*bb";//true
 s = "abddbbb";   p = "a*d*b";//true
 s = "abdb";      p = "a**";//true
 s = "a";         p = "a**";//true
最后,除了*这一个难点之外,题目中的edge case也不少。

如果用递归的话会超时。

class Solution {
public:
    bool isMatch(string s, string p)
    {
        int ss ;  
        int pp ;  
        bool has_star = false; 
        int s_index = 0;
        int p_index = 0;
        while (s_index < s.size() && (has_star || p_index < p.size())) 
        {  
            if (s[s_index] == p[p_index] || p[p_index] == '?') 
            {  
                ++s_index;  
                ++p_index;  
            }
            else if (p[p_index] == '*') 
            {  
                has_star = true;  
                if ((p_index+1) == p.size())  //当前这个*是p的最后一位 那就可以匹配全部了 
                    return true;  
                ss = s_index;       //ss记录s的当前位置
                pp = ++p_index;     //pp记录当前*的后一位
            } 
            else 
            {  
                if (!has_star)      
                    return false;  
                s_index = ++ss; //如果没匹配上,s_index回到
                p_index = pp;  
            }  
        }  
        
        while (p_index < p.size() && p[p_index] == '*')
            ++p_index;  

        return (s_index == s.size() && p_index == p.size()); 
    }
};






















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值