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
摘自
http://www.cnblogs.com/boring09/p/4246055.html
http://www.cnblogs.com/xiaoba1203/p/5626134.html
有技巧性的一道题,虽然本质上仍然是搜索+回溯,但关键是如何处理模式串里的多余的*,如果处理的不好就超时了。
基本的搜索+回溯算法是这样的,对于原串s和模式串p,依次遍历其字符:
(a) 如果p[j]="*",依次将p[j+1..p.length]和s[i..s.length]、s[i+1..s.length]、s[i+2..s.length]...匹配,如果全都失败了,将i和j回溯到上一个"*"号位置
(b) 如果s[i]="?"或s[i]=p[j],说明当前字符匹配,此时i++,j++
(c) 否则,说明当前字符不匹配,回溯至上一个星号位置
可以看出,如果"*"很多,而且总是失败,那么算法的回溯代价是巨大的
优化的地方在于:对于情况(a),如果当前匹配失败,就说明整个匹配失败了,不需要回溯至上一个星号处。
说白了就是,最多回溯到p串的上一个"*"号处,在往前的"*"不用管了。
例如:
0 1 2 3 4 5 6 7 8
s: a b c d a c c c
| | \ \ \ \
p: a b * c d * a c c
|
失配
上面的例子,s[5]!=p[6],那么最多只需要回溯到第二个星号位置(p[5]="*"),不需要回溯到第一个星号位置(p[2]="*")。因为回溯到更早的"*"不会产生新的匹配结果。
-------------------------------------------------------------------------------------------------------------------------------------
1.当str1与str2分别到了i和j的时候。同时在str2[j]的位置遇到了*(后面还有别的*的情况下)。
2.之前的方法是,找str1[i](包括str1[i])之后遇到的所有的str2[j]之后的第一个字母a(非*),然后再按照之前的规则进行匹配,遇到下一个*的时候也会按照刚才的规则进行判断,一旦,错误,将回到第一个*的地方重新进行判断。
3.这里就存在一个可以优化的点,就是在遇到下一个*的时候,如果已经匹配成功,那么就算之后匹配失败,其实也不用重新返回第一个*来进行判断,只需要回到当前的*处接着判断就可以了,这样的话其实不用递归会比较好写一点。
public static boolean isMatch(String s, String p)
{
int len1 = s.length(), len2 = p.length();
char[] str1 = s.toCharArray();
char[] str2 = p.toCharArray();
int i = 0, j = 0, pre = -1, before_i = -1, before_j = -1;
while (i < len1)
{
if (j < len2 && (str1[i] == str2[j] || str2[j] == '?'))
{
i++;
j++;
} else if (j < len2 && str2[j] == '*')
{
before_i = i;
before_j = j;
j++;
} else if (before_i != -1)
{
i = before_i;
j = before_j + 1;
before_i++;
} else
return false;
}
while (j < len2 && str2[j] == '*')
j++;
if (j == len2)
return true;
else
return false;
}
本文介绍了一种通配符匹配算法,该算法支持 '?' 和 '*' 两种通配符,并通过优化回溯过程来提高匹配效率。

437

被折叠的 条评论
为什么被折叠?



