The algorithm does not say, anyway, is based on string matching. Compare the KMP and Rabin-karp algorithms here.
< method one >KMP algorithm.
592788 |
Lizitong |
2462 |
Accepted |
4828 KB |
680 Ms |
C++/edit |
2349 B |
2014-03-29 19:07:02 |
#include <cstdio> #include <cstring> #include <algorithm>using namespace Std;int N,m,a,b,q;char map[ 1001][1001],s[11][101][1001];int next[500001],pos[1001];void getfail (char p[],int next[]) {next[0]=next[1]=0;for ( int i=1;i<m;i++) {int j=next[i]; while (J&&p[i]!=p[j]) j=next[j]; if (P[i]==p[j]) next[i+1]=j+1; else next[i+1]=0; }}int Find (char T[],char p[],int next[]) {N=strlen (T); M=strlen (P); Getfail (p,next); int j=0;for (int i=0;i<n;i++) {while (J&&p[j]!=t[i]) j=next[j];//if J becomes 0 still does not satisfy p[j]==t[i], Only I until p[j]==t[i] is present. if (P[j]==t[i]) j + +; if (j==m) return i-m+1; }return-1;} int main () {scanf ("%d%d%d%d", &n,&m,&a,&b), for (int i=0;i<n;i++) scanf ("%s", Map[i]), scanf ("%d", &Q), for (int i=1;i<=q;i++) for (int j=0;j<a;j++) scanf ("%s", S[i][j]), if (a==1) {for (int i=1;i<=q;i++) { BOOL Flag=false; for (int j=0;j<n;j++) if (Find (Map[j],s[i][0],next)!=-1) {flag=true;printf ("1\n"); Break } if (!flag) printf ("0\n"); } return 0; }for (int i=1;i<=q;i++) {bool Goal=false; for (int j=0;j<=n-a;j++) {bool flag=true; int max=0; while (Flag&&!goal) {for (int k=0;k<a;k++) {pos[k]=find (map[k+j]+max,s[i][k],next); if (pos[k]==-1) {flag=false; Break }} if (!flag) break; max=0; int count=0; for (int k=0;k<a;k++) {if (pos[k]==pos[0]) count++; Max=max (Max,pos[k]); } if (count==a) {goal=true; printf ("1\n"); }} if (goal) break; } if (!goal) printf ("0\n"); }return 0;}
< method two >rabin-karp algorithm.
820112 |
Lizitong |
2462 |
Accepted |
2880 KB |
980 Ms |
C++/edit |
3103 B |
2014-12-27 11:35:21 |
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;typedef unsigned long Long ull;const ull seed=31;ull seeds[1001];int N,m,a,b,q,pos[1001];char map[1001][1001],s[11][101][1001];// Brute force string comparison bool Strcmp (const char a[],const int &l1,const int &r1,const char b[],const int &l2,const int &r2) { for (int i=l1,j=l2;i<r1;++i,++j) if (A[i]!=b[j]) return 0;return 1;} Natural overflow, L first pointer, R tail pointer, left closed right open ull bkdrhash (const char str[],const int &l,const int &r) {ull res=0;for (int i=l;i<r;++i) Res=res*seed+str[i];return Res;} Preprocessing to facilitate the transfer of hash (S[i...i+m-1] and hash (s[i+1...i+m]) void Init_seeds () {seeds[0]=1;for (int i=1;i<1001;++i) seeds[i] =seeds[i-1]*seed;} Text string lookup, s text string, sub substring int rabinkarp (const char s[],const char sub[]) {int N=strlen (s), M=strlen (sub), Ull hsub=bkdrhash (Sub, 0,M), Hs=bkdrhash (S,0,m), for (int i=0;i<=n-m;++i) {if (hs==hsub && Strcmp (s,i,i+m,sub,0,m)) return i; Hs= (Hs-s[i]*seeds[m-1]) *seed+s[i+m];//o (1) transfer}return-1;} Int Main () {init_seeds (); scanf ("%d%d%d%d", &n,&m,&a,&b); for (int i=0;i<n;i++) scanf ("%s", Map[i]); scanf ("%d", &q); for (int i=1;i<=q;i++) for (int j=0;j<a;j++) scanf ("%s", S[i][j]); if (a==1) {for (int i=1;i<=q;i++) {bool Flag=false; for (int j=0;j<n;j++) if (Rabinkarp (map[j],s[i][0])!=-1) {flag=true; printf ("1\n"); Break } if (!flag) printf ("0\n"); } return 0; } for (int i=1;i<=q;i++) {bool Goal=false; for (int j=0;j<=n-a;j++) {bool flag=true; int max=0; while (Flag&&!goal) {for (int k=0;k<a;k++) {pos [K]=rabinkarp (Map[k+j]+max,s[i][k]); if (pos[k]==-1) { Flag=false; Break }} if (!flag) break; max=0; int count=0; for (int k=0;k<a;k++) {if (pos[k]==pos[0]) count++; Max=max (Max,pos[k]); } if (count==a) {goal=true; printf ("1\n"); }} if (goal) break; } if (!goal) printf ("0\n"); } return 0;}
Although the asymptotic complexity is the same, it is clear that KMP is more stable.
"KMP algorithm" "Rabin-karp algorithm" [BeiJing2011] Matrix template