KMP

void find(char* T, char* P) {
    int n = strlen(T), m = strlen(P);
    getFail(P, f);
    int j = 0;                              //当前结点编号,初始为0号结点
    for(int i = 0; i < n; i++) {            //文本串当前指针
        while(j && P[j]!=T[i]) j = f[j];    //顺着是失配边走,直到可以匹配
        if(P[j] == T[i]) j++;
        if(j == m) printf("%d\n", i-m+1);   //找到了
    }
}

为什么要顺着失配边走?:每次沿失配边走都是当前状态的尽可能最大值

void getFail(char* P, int* f) {
    int m = strlen(P);
    f[0] = 0; f[1] = 0;
    for(int i = 1; i < m; i++){
        int j = f[i];
        while(j && P[i]!=P[j]) j = f[j];
        f[i+1] = P[i] == P[j]? j+1 : 0;
    }
}

T:文本串
P:模式串
f[i]:P的前i长度子串中前后对称的最大长度(不含"全"(j > f[j]))

posted @ 2019-06-10 20:47  Hanasaki  阅读(121)  评论(0)    收藏  举报