模式匹配算法都需要一个源串的滑动指针i和模式串的滑动指针j。普通的匹配算法在字符失配时需要同时回溯i和j,复杂度为o(m*n)。而改进的KMP匹配算法算法就是在失配时不回溯源串指针i,只回溯j到最长前缀处使得复杂度达到哦o(n)。而Sunday算法不仅不回溯i,而且可以使i跨越模式串前进,进一步降低复杂度,而且如果不谈Sunday算法的原理,单就算法本身和实现来讲要比KMP算法简单很多,更加容易理解。KMP算法的关键NEXT数组的创建对于刚接触的人来说还是有一定的理解难度的。关于KMP算法,见上一篇博文KMP字符串匹配算法的分析实现。下边是Sunday算法的流程:
1. i,j分别指向源串和模式串首, m指向源串中与模式串长度相等的后一位置m= i + pattern.size();
2. 滑动i,j, j == pattern.size() - 1,则返回,失配则执行3
3. 向右滑动模式串直到找到一个与m匹配的位置,重新设置i为当前与模式串首字符对齐的字符在源串的位置, m= i + pattern.size(),执行2
算法的图示和示例Sunday算法百度百科 讲的非常详细。接下来贴上简单的算法实现:
int SundaySearch(string text, string pattern){
int i = 0, j = 0, k;
int m = pattern.size();
if(pattern.size() <= 0 || text.size() <= 0)
return -1;
for(; i<text.size();) {
if(text[i] != pattern[j]) {
for(k=pattern.size() - 1; k>=0; k--) {
if(pattern[k] == text[m])
break;
}
i = m-k;
j = 0;
m = i+pattern.size();
}
else {
if(j == pattern.size()-1)
return i-j;
i++;
j++;
}
}
return -1;
}