RabinKarp.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // recherche de motif 2D
  2. // input : text n*m matrix; pattern x*y matrix
  3. // compléxité : linéaire
  4. #define uint unsigned int
  5. const int A=2001, B = 2001; // maximum sizes
  6. const uint E=27;
  7. char text[A][A], patt[B][B]; // [x][y]
  8. uint ht, hp, pw[B*B], hor[A], ver[A][A];
  9. int n, m, x, y;
  10. void init() { // call only once
  11. int i, j = B*B;
  12. for(i=1, pw[0]=1; i<j; ++i) pw[i]=pw[i-1]*E;
  13. }
  14. void hash() { // call before count
  15. int i, j;
  16. for(i=0; i<n; ++i)
  17. for(j=0, hor[i]=0; j<y; ++j) {
  18. hor[i]*=pw[x]; hor[i]+=text[i][j]-'a';
  19. }
  20. for(j=0; j<m; ++j) {
  21. for(i=0, ver[0][j]=0; i<x; ++i) {
  22. ver[0][j]*=E; ver[0][j]+=text[i][j]-'a';
  23. }
  24. for(i=1; i<=n-x; ++i)
  25. ver[i][j]=(ver[i-1][j]-(text[i-1][j]-'a')*pw[x-1])
  26. *E+text[i+x-1][j]-'a';
  27. }
  28. for(j=0, ht=hp=0; j<y; ++j)
  29. for(i=0; i<x; ++i) {
  30. ht*=E; ht+=text[i][j]-'a';
  31. hp*=E; hp+=patt[i][j]-'a';
  32. }
  33. }
  34. int count() {
  35. if (n==0||m==0||x==0||y==0) return 0;
  36. int i, j, cnt=0; uint t;
  37. for(i=0; i<=n-x; ++i) {
  38. for(j=0, t=ht; j<=m-y; ++j) {
  39. if(t==hp) ++cnt;
  40. t=(t-ver[i][j]*pw[y*x-x])*pw[x]+ver[i][j+y];
  41. }
  42. ht=(ht-hor[i]*pw[x-1])*E+hor[i+x];
  43. }
  44. return cnt;
  45. }