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());
}
};