RabinKarp.cpp 1.1 KB

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