Wildcard Matching(通配符的匹配)
【难度:Hard】
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和p的时候,我们可以分出四种情况:
- 1)当前字符匹配:
s[i]==p[j] || p[j] == '?'
时,两者下标同时右移一位,继续匹配; - 2)当前字符不匹配,但是出现了通配符
'*'
:p[j] == '*'
,这时要记录'*'
在p中出现的下标位置,和此时s的下标i。p的下标j右移一位; - 3)当前字符不匹配,
p[j] != '*'
,但是之前出现过通配符'*'
时,将s[i]与'*'
匹配,s的下标右移一位。 - 4)当前字符不匹配,
p[j] != '*'
,同时之前没有出现过通配符'*'
,匹配失败,返回false。
最后如果s匹配结束,还要判断p中的剩余字符是否为'*'
,若出现非'*'
字符,说明匹配失败。
本题主要利用了回溯的思想来判断何时返回到标记位置继续进行匹配。
c++代码如下:
class Solution {
public:
bool isMatch(string s, string p) {
int index_s = 0;
int index_p = 0;
int star_p = -1;
int mark_s = 0;
while (index_s < s.size()) {
//当前字符匹配
if (s[index_s] == p[index_p] || p[index_p] == '?') {
index_s++;
index_p++;
} else if (p[index_p] == '*') {
//出现'*',记录当前位置
star_p = index_p;
mark_s = index_s;
index_p++;
} else if (star_p != -1) {
//不匹配且之前出现'*'时,回溯
index_p = star_p+1;
index_s = mark_s+1;
mark_s++;
} else {
//不匹配且无'*'出现时,返回false
return false;
}
}
while (index_p < p.size()) {
if (p[index_p] == '*')
index_p++;
else
return false;
}
return true;
}
};