bhupixb

Rolling Hash to find pattern in a String

Sep 27th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.74 KB | None | 0 0
  1. // I can't tell you what it really is,
  2. // I can only tell you what it feels like.
  3. #include "bits/stdc++.h"
  4. using namespace std;
  5.  
  6. #define int long long
  7. #define F first
  8. #define S second
  9. #define sz(x) ((int)x.size())
  10. #define rep(i,a,n) for (int i = a; i <= n; ++i)
  11. #define all(v) v.begin(), v.end()
  12. #define pb push_back
  13. #define P pair < int, int >
  14. #define E cout << '\n'
  15.  
  16. int add(int, int, int);
  17. int mul(int, int, int);
  18. int po(int, int, int);
  19. int sub(int, int, int);
  20.  
  21. const int mod1 = 1e9 + 7;
  22. const int mod2 = 1e9 + 9;
  23. const int p1 = 31;
  24. const int p2 = 37;
  25.  
  26. const int N = 1e6 + 5;
  27.  
  28. int pl1[N], pl2[N];
  29.  
  30. void pre() {
  31. pl1[0] = 1, pl2[0] = 1;
  32. for (int i = 1; i < N; ++i) {
  33. pl2[i] = mul(p2, pl2[i-1], mod2);
  34. pl1[i] = mul(p1, pl1[i-1], mod1);
  35. }
  36. }
  37.  
  38. inline void solve() {
  39. string text, patt;
  40. vector < int > v;
  41. int n, m;
  42. cin >> text >> patt;
  43. n = text.size(), m = patt.size();
  44. if (m > n) {
  45. cout << "Not Found\n\n";
  46. return;
  47. }
  48. text = '!' + text;
  49. patt = '!' + patt;
  50.  
  51. vector < int > h1(n+1), h2(n+1); // Hash in base p1 and p2;
  52.  
  53. for (int i = 1; i <= n; ++i) {
  54. h1[i] = add(mul(h1[i-1], p1, mod1), text[i] - 'a' + 1, mod1);
  55. h2[i] = add(mul(h2[i-1], p2, mod2), text[i] - 'a' + 1, mod2);
  56. }
  57.  
  58. int cur1 = 0, cur2 = 0;
  59. for (int i = 1; i <= m; ++i) {
  60. cur1 = add(mul(cur1, p1, mod1), patt[i] - 'a' + 1, mod1);
  61. cur2 = add(mul(cur2, p2, mod2), patt[i] - 'a' + 1, mod2);
  62. }
  63.  
  64. auto find = [&] (int l, int r) {
  65. if (l == 1) {
  66. return make_pair(h1[r], h2[r]);
  67. }
  68. int x = sub(h1[r], mul(h1[l-1], pl1[r-l+1], mod1), mod1);
  69. int y = sub(h2[r], mul(h2[l-1], pl2[r-l+1], mod2), mod2);
  70. return make_pair(x, y);
  71. };
  72. pair < int, int > p = make_pair(cur1, cur2);
  73.  
  74. for (int i = 1; i + m - 1 <= n; ++i) {
  75. if (p == find(i, i+m-1)) {
  76. v.push_back(i);
  77. }
  78. }
  79.  
  80. if (!v.empty()) {
  81. cout << v.size() << '\n';
  82. for (int x : v) {
  83. cout << x << ' ';
  84. }
  85. cout << "\n\n";
  86. }
  87. else {
  88. cout << "Not Found\n\n";
  89. return;
  90. }
  91. }
  92.  
  93. signed main() {
  94. ios_base::sync_with_stdio(0);
  95. cin.tie(NULL);
  96. cout.tie(NULL);
  97. int t = 1;
  98. pre();
  99. cin >> t; while(t--)
  100. solve();
  101. return 0;
  102. }
  103. inline int add(int x, int y, int mod) {
  104. if (x >= mod) x %= mod;
  105. if (y >= mod) y %= mod;
  106. x += y;
  107. return (x >= mod ? x - mod : x);
  108. }
  109. inline int mul(int x, int y, int mod) {
  110. if (x >= mod) x %= mod;
  111. if (y >= mod) y %= mod;
  112. return (x*y) % mod;
  113. }
  114. inline int sub(int x, int y, int mod) {
  115. return ((x-y)%mod+mod) % mod;
  116. }
  117. int po(int x, int n, int mod) {
  118. int res = 1;
  119. for (;n > 0;) {
  120. if (n & 1) {
  121. res = mul(res, x, mod);
  122. }
  123. x = mul(x, x, mod);
  124. n /= 2;
  125. }
  126. return res;
  127. }
Add Comment
Please, Sign In to add comment