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
题目要求如上所示,“?”能匹配单个字符,“*”能匹配任意字符串,包括空字符串。
解题思路如下:
对于s的每个字符:
1.当s的第i个字符s[i]等于p的第j个字符p[j],或者p[j]为“*”的时候,i和j增加1;
2.当p[j]为*的时候,需要记录p的当前位置aterisk,并且此时的s[i]一定匹配上,记录此时s的下标lastMatch,另外i增加1,j不变,表示*号与空字符匹配;
3.如果当前匹配失败的时候,如果之前出现了“*”,即aterisk的下标不为初始值-1,那么有可能后面的能继续匹配上,因此,j重新返回下标aterisk+1,lastMatch下标加1(*号匹配的字符增加1),i再从当前lastMatch开始继续匹配。
4.最后仍需要判断,如果p没有结束,并且p剩下的部分有非“*”的存在,则说明没有匹配上。
代码实现如下:
class Solution {
public:
bool isMatch(string s, string p) {
int ps = 0, pp = 0, lastMatch = 0, asterisk = -1;
while (ps < s.length()) {
// s, p当前两个字符匹配
if (s[ps] == p[pp] || p[pp] == '?')
ps++, pp++;
// p的字符是星号, 记录位置, 挪动pp向后一位
else if (p[pp] == '*')
asterisk = pp++, lastMatch = ps;
// 以上情况都不是, 我们返回上一次星号的位置拿星号匹配
else if (asterisk > -1)
ps = ++lastMatch, pp = asterisk + 1;
// 如果之前连星号都没出现过, 直接返回不匹配
else return false;
}
// 看看p剩余的字符串里面有没有除了星号以外的字符
while (pp < p.length() && p[pp] == '*') pp++;
return pp == p.length();
}
};