杭电acm1711(kmp算法)
遇到看毛片算法,表示压力山大,想了有三天,各种调试错误,在next函数的调试上想了两天,用了两种写法,后来发现用一个循环,边比较,指针边移动或回溯,比较好,也较容易理解,菜鸟无解啊
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h>//按kmp论文原来的模式 2 int next[10005],a[1000020],b[10010]; 3 void kmp(int m)//计算模式串中的next函数值,存入数组next中 4 { 5 int j,i; 6 next[1]=0; 7 i=1; 8 j=0; 9 while(i<m) 10 { 11 if(j==0||b[j-1]==b[i-1])//比较成功,继续比较后续字符 12 { 13 i++; 14 j++; 15 next[i]=j; 16 } 17 else j=next[j]; 18 }//next函数处置next[1]=0,即数组next的下标从1开始,0号单元空闲 19 } 20 int KMP(int n,int m)//在目标串中找模式串首次出现的位置,不存在返回-1 21 { 22 int i=1,j=1; 23 while(i<=n&&j<=m) 24 { 25 if(j==0||a[i-1]==b[j-1])//比较成功就两个指针都后移, 这里i和j都从1开始,比较的时候都是i-1或j-1 26 { 27 i++; 28 j++; 29 } 30 else j=next[j];//否则j指针回溯 31 } 32 if(j==m+1) 33 return i-m;//返回首次出现的位置 34 else return (-1); 35 } 36 int main() 37 { 38 int i,j,t; 39 int n,m; 40 scanf("%d",&t); 41 while(t--) 42 { 43 scanf("%d%d",&n,&m); 44 for(i=0;i<n;i++) 45 scanf("%d",&a[i]); 46 for(j=0;j<m;j++) 47 scanf("%d",&b[j]); 48 kmp(m); 49 printf("%d\n",KMP(n,m)); 50 } 51 return 0; 52 }