HDU 1711 Number Sequence (KMP找子串第一次出現的位置)(基礎模板題)
阿新 • • 發佈:2019-02-12
題意:給出若干個樣例,每個樣例包括兩個字串,如果第二個字串是第一個字串的子串,則求他第一次出現的位置,不是子串的話輸出-1.
思路:kmp演算法的模板題
對nexts陣列如何構造解釋:
根據定義nexts[0]=-1,假設nexts[j]=k, 即P[0...k-1]==P[j-k,j-1]
1)若P[j]==P[k],則有P[0..k]==P[j-k+1,j],很顯然,nexts[j+1]=nexts[j]+1=k+1;
2)若P[j]!=P[k],則可以把其看做模式匹配的問題,即匹配失敗的時候,k值如何移動,顯然k=nexts[k]。
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; const int MAXN=1000010; int a[MAXN]; int b[MAXN]; int n,m; int nexts[MAXN]; /* 根據定義nexts[0]=-1,假設nexts[j]=k, 即P[0...k-1]==P[j-k,j-1] 1)若P[j]==P[k],則有P[0..k]==P[j-k+1,j],很顯然,nexts[j+1]=nexts[j]+1=k+1; 2)若P[j]!=P[k],則可以把其看做模式匹配的問題,即匹配失敗的時候,k值如何移動,顯然k=nexts[k]。 */ void getnexts() { int j,k; nexts[0]=-1; j=0; k=-1; while(j<m) { if(k==-1||b[j]==b[k]) { j++; k++; nexts[j]=k; } else k=nexts[k]; } } int KMP_Index() { int i=0,j=0; getnexts(); while(i<n&&j<m) { if(j==-1||a[i]==b[j]) { i++;j++; } else j=nexts[j]; } if(j==m)return i-m+1; else return -1; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++)scanf("%d",&a[i]); for(int i=0;i<m;i++)scanf("%d",&b[i]); printf("%d\n",KMP_Index()); } return 0; }