HDU 1711 kmp入门

来源:互联网 发布:java怎么输入数组 编辑:程序博客网 时间:2024/05/16 02:02

点击打开链接

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;const int M = 1001000;int n,m; int a[M],b[10100];int Next[10100];// next[j]=k  当b[j]失配时 应回溯到k继续匹配  //条件: 若b[j] 与 a[i] 失配时能 如果能回溯到 b[k]//  则需要条件: "b1..bk-1"== "ai-(k-1)....ai-1"   //利用 b[j] 即部分匹配的结果 可以得到 " bj-(k-1)....bj-1"  ="ai-(k-1)....ai-1"// 所以对模式串进行 预处理 如果 "b1....bk-1"  == "bj-(k-1)....bj-1"//                   即条件成立 此时 b[j]失配时 可以回溯到k void Get_next(int m){Next[1]=0;int i=1,k=0; // k=0只能回溯到1 while(i<=m){// 已知next[i]=k 递推求 next[i+1]? // 因为"b1..bk-1"=="bi-(k-1).....bi-1"// 若bi==bk 则"b1..bk"=="bi-(k-1)...bi"  if(k==0||b[i]==b[k]) {Next[i+1]=k+1;i++;k++;}//// bi!=bk  此时自己匹配自己 !! //则 此时bk!=bi 相当于在bk处失配 // 则k不断回溯 知道 bk'=bi // 则此时 "b1.. bk'-1 "=="bi-(k'-1).....bi-1" else{k=Next[k];}}}void Kmp(){int i=1,j=1;while(i<=n&&j<=m){//j==0 即s[i]位置上没救了 主串前移 if(j==0 || a[i]==b[j]){i++;j++;}else{j=Next[j]; // 失配时 回溯模式串j即可 }}if(j>m)cout<<i-m<<endl;elsecout<<-1<<endl;}int main(){int t;cin>>t;while(t--){cin>>n>>m;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=m;i++){scanf("%d",&b[i]);}Get_next(m);Kmp(); }return 0;} 


0 0
原创粉丝点击