#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
void prefix_table(char pattern[], int prefix[], int n){
prefix[0] = 0;
int i = 1; //从prefix[1]开始计算
int len = 0; //一开始前缀为0
while( i < n ){
if( pattern[len] == pattern[i] ){// len = prefix[i-1]
len++;
prefix[i]=len;
i++;
}
else {
if( len > 0 ){ //例子: ABABCABAA(求末尾)
len = prefix[len-1];
} //比较的步骤是相同的 放在下一处循环中
else {
prefix[i] = len;
i++;
}
}
}
}
void prefix_table_move(int prefix[],int n){
int i;
for( i = n-1; i > 0; i-- ){
prefix[i] = prefix[i-1];
}
prefix[0] = -1;
}
void kmp_search(char text[], char pattern[]){
int n = strlen(pattern);
int m = strlen(text);
int *prefix= (int*)malloc(sizeof(int) * n);
prefix_table(pattern, prefix, n);
prefix_table_move(prefix, n);
int i = 0, j = 0;
while( i < m ){
if( text[i] == pattern[j] ){
i++;
j++;
}
else {
j = prefix[j];
if(j == -1){
i++;
j++;
}//j=0;i=下一个位置
}
if(j == n-1 && text[i] == pattern[j]){ //检测到最后一个,且他们相等时,找到字符串
printf("Found pattern at %d\n", i-j);
j = prefix[j];//重新开始寻找
}
}
}
int main(){
char pattern[] = "ABACABAA";
char text[] = "ABABABACABAAABABBCA";
kmp_search(text, pattern);
}
喵~贴上学习视频
https://www.bilibili.com/video/av11866460?from=search&seid=18104078040614528561
https://www.bilibili.com/video/av16828557?from=search&seid=18104078040614528561