//复杂度O(n+m)
//求最大公共前后缀
#define SIZE 100
void calc_lcp(int* d, const char* p)
{
//初始化,从一开始到最后。从0开始到最后第二个。求公共部分
int i = 1, j = 0, np = strlen(p);
//d[0]为0
memset(d, 0, sizeof(int) * np);
while (i < np)
{
//相等
if (p[i] == p[j])
{
//d数组赋值,j是下标
d[i++] = ++j;
}
//不相等
else
{
//j大于0, 回溯再比较
if (j > 0) j = d[j - 1];
//j等于0,j无法移动了,只能i++
else i++;
}
}
}
void kmp(const char* t, const char* p)
{
int d[SIZE];
//初始化参数
int i = 0, j = 0, nt = strlen(t), np = strlen(p);
//求最大公共前后缀
calc_lcp(d, p);
//边界:主串遍历完
while (i < nt)
{
//相同
if (t[i] == p[j])
{
i++, j++;
//模式串遍历完
if (j == np)
{
printf("%d\n", i - np);
return;
}
}
else
{
if (j > 0) j = d[j - 1];
else i++;
}
}
printf("%d\n", -1);
return ;
}
int main(void)
{
kmp("ABABABABC", "ABAB");
kmp("ABABCABAB", "ABAB");
kmp("AAAAAAA", "AAA");
kmp("ABABABC", "ABABC");
kmp("XYXZdeOXZZKWXYZ", "WXYZ");
kmp("GCAATGCCTATGTGACCTATGTG", "TATGTG");
kmp("AGATACGATATATAC", "ATATA");
kmp("CATCGCGGAGAGTATAGCAGAGAG", "GCAGAGAG");
return 0;
}
28.求子串出现的一个的位置
最新推荐文章于 2022-11-18 09:30:20 发布