kmp學習筆記
阿新 • • 發佈:2018-07-04
字符串 strlen 網上 hdu printf scan print efi 下標
kmp學習筆記
說再前邊
字符串水平基本為0,學了第4遍KMP了,總是忘。。。網上資料很多,就不詳細講解了。
一些知識
- 循環節大小:n - nxt[n]
模板[HDU2087]
下標從0開始
nxt[i] 為滿足p[i-z...i-1]=p[0...z-1]最大的z值
#include <cstdio> #include <cstring> #define rep(i,a,b) for(int i=a;i<=b;++i) typedef long long ll; const int N = 100000 + 7; using namespace std; char s[N], p[N]; int nxt[N], n, m; void getnxt() { int i, j; j = nxt[0] =-1; i = 0; while(i < m) { while(j != -1 && p[i] != p[j]) j = nxt[j]; nxt[++i] = ++j; } } int kmp_ct() { int i, j; int ans = 0; i = j = 0; while(i <= n) { while(j != -1 && s[i] != p[j]) j = nxt[j]; ++i; ++j; if(j >= m) { ++ans; j = 0;//不可重疊 //j = nxt[j] 可以重疊 } } return ans; } int main() { while(~scanf(" %s", s)) { if(s[0] == ‘#‘) break; scanf(" %s", p); n = strlen(s), m = strlen(p); getnxt(); printf("%d\n",kmp_ct()); } return 0; }
下標從1開始
#include <cstdio> #include <cstring> using namespace std; const int N=1e6+5; int T,nxt[N],n,m; char s[N],p[N]; void getnxt(char p[],int n){ nxt[1]=0; for(int i=2;i<=n;i++){ int j=nxt[i-1]; while(j&&s[j+1]!=s[i]) j=nxt[j]; if(s[j+1]==s[i]) nxt[i]=j+1; else nxt[i] = 0; } } int kmp(){ int ans=0; getnxt(p,m); int j=0; for(int i=1;i<=n;i++){ while(j&&p[j+1]!=s[i]) j=nxt[j]; if(p[j+1]==s[i])++j; if(j==m) { ans++; j=0; } } return ans; } int main(){ while(scanf(" %s",s+1)!=EOF){ if(s[1] == ‘#‘) break; scanf(" %s",p+1); n=strlen(s+1),m=strlen(p+1); printf("%d\n",kmp()); } return 0; }
kmp學習筆記