Advertisement
cmiN

rabin-karp (fail)

Mar 8th, 2012
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.87 KB | None | 0 0
  1. /*
  2.  * Fail example of Rabin-Karp for string matching.
  3.  * It takes O(NlogN) (not linear).
  4.  * Also on some examples it gives wrong answer.
  5.  * Just for code fun, not efficient.
  6.  */
  7.  
  8.  
  9. #include <iostream>
  10. #include <fstream>
  11. #include <vector>
  12. #include <string>
  13. #include <algorithm>
  14. #include <queue>
  15. using namespace std;
  16.  
  17.  
  18. class Hash {
  19.     /**
  20.      * Simple hashing class.
  21.      * Works with string objects.
  22.      * Optimized update.
  23.      *
  24.      * Hash(arg) -> make hash
  25.      * get() -> get hash
  26.      * del() -> erase first char
  27.      * add() -> append char
  28.      */
  29.  
  30.     private:
  31.     typedef unsigned int hash_type;
  32.     static const hash_type MOD1 = 63013, MOD2 = 51337;
  33.     static const hash_type BAS1 = 101, BAS2 = 13; // base
  34.     hash_type hash1, hash2, exp;
  35.     queue<char> que;
  36.  
  37.     hash_type power(hash_type bas, hash_type expo, hash_type mod)
  38.     {
  39.         /// Logarithmic exponentiation. Here I have logN.
  40.         hash_type res = 1;
  41.         while (expo) {
  42.             if (expo % 2) res = (res * bas) % mod;
  43.             bas = (bas * bas) % mod;
  44.             expo /= 2;
  45.         }
  46.         return res;
  47.     }
  48.  
  49.     public:
  50.     Hash(string arg="")
  51.     {
  52.         hash1 = hash2 = 0;
  53.         exp = arg.size() - 1;
  54.         for (int i = 0; i <= exp; ++i) {
  55.             que.push(arg[i]);
  56.             hash1 = (hash1 + arg[i] * power(BAS1, exp - i, MOD1)) % MOD1;
  57.             hash2 = (hash2 + arg[i] * power(BAS2, exp - i, MOD2)) % MOD2;
  58.         }
  59.     }
  60.  
  61.     hash_type get(int which) const
  62.     {
  63.         if (which == 1) return hash1;
  64.         return hash2;
  65.     }
  66.  
  67.     void del()
  68.     {
  69.         if (que.empty()) return;
  70.         hash1 -= (que.front() * power(BAS1, exp, MOD1)) % MOD1;
  71.         hash2 -= (que.front() * power(BAS2, exp, MOD2)) % MOD2;
  72.         que.pop();
  73.     }
  74.  
  75.     void add(char chr)
  76.     {
  77.         hash1 = (hash1 * BAS1 + chr) % MOD1;
  78.         hash2 = (hash2 * BAS2 + chr) % MOD2;
  79.         que.push(chr);
  80.     }
  81.  
  82.     bool operator==(const Hash& arg) const
  83.     {
  84.         bool test1 = get(1) == arg.get(1) ? true : false;
  85.         bool test2 = get(2) == arg.get(2) ? true : false;
  86.         if (test1 && test2) return true;
  87.         return false;
  88.     }
  89. };
  90.  
  91.  
  92. const int DIM = 1000;
  93. string str, pat;
  94. vector<int> matchPos;
  95.  
  96.  
  97. void solve()
  98. {
  99.     Hash patHash(pat);
  100.     int ind = min(pat.size(), str.size());
  101.     Hash strHash(str.substr(0, ind));
  102.     for (; matchPos.size() < DIM; ++ind) {
  103.         if (patHash == strHash) matchPos.push_back(ind - pat.size());
  104.         if (ind == str.size()) break;
  105.         strHash.del();
  106.         strHash.add(str[ind]);
  107.     }
  108. }
  109.  
  110.  
  111. int main()
  112. {
  113.     ifstream fin("strmatch.in");
  114.     ofstream fout("strmatch.out");
  115.     fin >> pat >> str;
  116.     solve();
  117.     fout << matchPos.size() << '\n';
  118.     for (int i = 0; i < matchPos.size(); ++i) fout << matchPos[i] << ' ';
  119.     fin.close();
  120.     fout.close();
  121.     return 0;
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement