#include<stdio.h> #include<string.h> #include<iostream> using namespace std; void get_next_one(char *a, int *next) { int i = 1, j = 0; next[1] = 0; while (i < a[0] - '0') { if (j == 0 || a[i] == a[j]) { i++; j++; next[i] = j; } else j = next[j]; } } //aaaaax的next[] //i=1 next[1]=0 //i=2 a2a1 next[2]=1 //i=3 a3a2 next[3]=2 因为a[3]=a[2] j的值保留,j=2 //i=4 a4a3 next[4]=3 j=3 //i=5 a5a4 next[5]=4 j=4 //i=6 j=5 next[6]=5 //aaaaax->next[]=012345 //错误的推论,但是跟下面的get_next的改进动机一致 //i=6 j=next[5]=4 x6-a4 不等 j=next[4] //i=6 j=3 x6-a3 不等 j=next[3]=2 //i=6 j=2 x6-a2 不等 j=next[2]=1 //i=6 j=1 x6-a1 不等 j=next[1]=0 //i=6 //|a|a|a|a|b|b|c|d <i=5> // | //|a|a|a|a|a|x| j=5 j开始回溯,j=next[j] // |a|a|a|a|a|x| j=4 ,然后j=next[4]=3 // |a|a|a|a|a|x| j=3 // |a|a|a|a|a|x| j=2 // |a|a|a|a|a|x| j=1 因为j=1为a,跟i=5的b不同,所以i增加,然后j取next[1]=1 //|a|a|a|a|b|b|c|d <i=6> i增加 // | // |a|a|a|a|a|x| j=1 //可见,中间的那几步都是多余的 //改进后的next数组为 //i=1 next[1]=0 初始化 j=0 //i=2 a2a1 next[2]=next[1]=0 j=1 //如果a[i]==a[j]的时候,j的值就递增 //i=3 j=2 a3a2 next[3]=next[2]=0 //i=4 j=3 a4=a3 next[4]=0 //i=5 j=4 a5=a4 next[5]=0 //i=6 j=5 a6!=a5 next[6]=5 //aaaaax新的next[]=000005 //ababaaaba //next[1]=0 i=1 j=0 //i++ i=2 j++ j=1 a!=b next[2]=j=1 //j=next[1]=0 //i++ i=3 j=1 a=a next[3]=next[1]=0 // i=4 j=2 b=b next[4]=next[2]=1 // i=5 j=3 a=a next[5]=next[3]=0 // i=6 j=4 a!=b next[6]=4 //j=next[4]=1 因为a[6]=a a[1]=a // i=7 j=2 a!=b next[7]=2 //j=next[2]=1 a[7]=a a[1]=a // i=8 j=2 b=b next[8]=next[2]=1 // i=9 j=3 a=a next[9]=next[3]=0 //ababaaaba->next[]=010104210 void get_next(char *a, int *next) { int i = 1, j = 0; next[1] = 0; while (i < a[0]-'0') { if (j == 0 || a[i] == a[j]) { i++; j++; if (a[i] != a[j]) next[i] = j; else next[i] = next[j]; } else j = next[j]; } } int index_kmp(char *A, char *a, int *next, int pos) { int i = pos; int j = 1; while (i <= A[0]-'0' && j <= a[0]-'0') { if (A[i] == a[j] || j == 0) { i++; j++; } else j = next[j]; } if (j > a[0]-'0') return i - (a[0]-'0'); else return 0; } #define MAX 100 int main() { char A[MAX], a[MAX]; int next[MAX]; scanf("%s %s", A, a); int Alen = strlen(A); int alen = strlen(a); cout << Alen << "dddd" << alen << endl; int i; for (i = Alen - 1; i >= 0; i--) A[i + 1] = A[i]; for (i = alen - 1; i >= 0; i--) a[i + 1] = a[i]; A[Alen + 1] = '\0'; a[alen + 1] = '\0'; cout << A << endl; cout << a << endl; A[0] = Alen+'0'; a[0] = alen+'0'; cout << A[0] << "dddd" << a[0] << endl; next[0] = alen; get_next(a, next); next[alen + 1] = '\0'; int t = 0; while (t <= alen) { cout << next[t] << ""; t++; } cout << endl; printf("%d\n", index_kmp(A, a, next, 1)); return 0; }
#include<stdio.h> #include<stdlib.h> #include<string.h> int index(char s[], char p[]) { int slen = strlen(s); int plen = strlen(p); int is=0, jp=0; while (is < slen && jp < plen) { if (s[is] == p[jp]) { is++; jp++; } else { is = is - jp + 1; jp = 0; } } if (jp > plen) return is - jp; //return is-plen; return -1; } #define MAX 101 //比如cdcda a[4]=cdcda next[4]=00120 //后面的和前面的进行比较,后面用i表示,前面的用j索引 //d和c c和c 相同d和d a和c //adsfadsfe d-a s-a f-a a-a d-d s-s f-f e-a //多条件控制 //a[i]==a[j]--后面的和前面的相等时候,cdc,a[j=1]=c a[i=4]=c 继续递增比较 //j==0--后面和前面不想等时候进入比较流程 //while结构,可以在循环里干其他事情,只要迭代值不增加;比如迭代5次对应5个元素的比较,可以在每一次之后进行一个j=next[j]但是迭代值i不增加 //默认都是0,只有满足后面的等于前面的,才会修改这个值,否则自动循环下去,知道迭代完成 void get_next(int *next, char *a, int la) { int i = 1, j = 0; next[1] = 0; while (i <= la) { if (a[i] == a[j] || j == 0) { //当前i和第一个不相同时候靠j==0去判断后一个和第一个;相同时,靠a[i]==a[j]去判断,后一个和第二个,j的值保留 j++; i++; if (a[i] == a[j]) // next[i] = j; } else j = next[j]; } } //a|b|c|a|b|a|b|c <i=6> // | //a|b|c|a|b|x| // |a|b|c|a|b|x 回溯i=2 // |a|b|c|a|b|x i=3 // |a|b|c|a|b|x i=4 // |a|b|c|a|b|x i=5 //a|b|c|a|b|a|b|c <i=6> // | // |a|b|c|a|b|x i=6 //回溯后发现,是在j=3的时候跟i=6的元素进行比较,相当于j=next[j] int str_kmp(int *next, char *A, char *a, int lA, int la) { int i=1, j=1, k; while (i <= lA&&j <= la) { if (A[i] == a[j] || j == 0) { i++; j++; } else j = next[j]; } if (j > la) return i - j + 1; else return -1; } int main() { int n, k; int next[MAX] = { 0 }; int lA=0, la = 0; char A[MAX], a[MAX]; scanf("%s %s", A, a); lA = strlen(A); la = strlen(a); for (k = la - 1; k >= 0; k--) { a[k + 1] = a[k]; } for (k = lA - 1; k >= 0; k--) { A[k + 1] = A[k]; } get_next(next, a, la); for (n = 1; n < MAX; n++) printf("%d ", next[n]); putchar('\n'); k = str_kmp(next, A, a, lA, la); if (-1 == k) printf("No so"); else printf("%d", k); return 0; }
kmp
最新推荐文章于 2023-01-23 18:57:44 发布