- 实现原理:
给定的字符母串S(长度为n)和子串T(长度为m),从左到右开始匹配,之后出现不匹配的情况后,判断母串S参与匹配的最后一位的下一位字符,如果该字符出现在子串T中,选择子串中最右面出现的位置进行对齐;否则直接跳过该匹配区域。
平均时间复杂度是O(n),最坏降低到O(n*m) - 详细的图解可以参考我看到的以下博客介绍
Sunday算法的图解教程1
Sunday算法的图解教程2
个人觉得两个联系起来看更方便有效,情况涵盖就比较全了。 - 代码
#include<bits/stdc++.h>
using namespace std;
int* GetNext(char* T)
{
int* pNext = NULL;
pNext = (int*)malloc(sizeof(int)*256);
memset(pNext,-1,sizeof(int)*256);
int len = strlen(T);
for (int i = 0; i <len; ++i){
pNext[T[i]] = i; //为获取具有相同字符中位于最右边的index
}
return pNext;
}
int Sunday(char* S, char* T)
{
if(S == NULL || T == NULL)
return -1;
int *pNext = GetNext(T);
int i = 0;
int j = 0;
int k = i;
int S_len = strlen(S);
int T_len = strlen(T);
while(i<S_len && j<T_len){
while(S[i] == T[j] && j < T_len){
i++;
j++;
}
//结束
if(j >= T_len){
return i-j;
}
//跳转
if(k+T_len < S_len){
k = k+T_len-pNext[S[k+T_len]]; //移动位数 = 模式串长度 + 1
i = k;
j = 0;
}else{
return -1;
}
}
return -1;
}
int main()
{
int n = Sunday("Today is a wonderful day","wonder");
printf("%d\n",n);
return 0;
}