1+ #include < iostream>
2+ #include < vector>
3+
4+ #define q 1000000007l
5+ #define x 31
6+
7+ class RabinKarp
8+ {
9+ public:
10+ RabinKarp (std::string const & pattern, std::string const & text): _pattern(pattern) {
11+ // std::cout << __FUNCTION__ << std::endl;
12+ _length = pattern.length ();
13+ _patternHash = hash (pattern.c_str ());
14+ check (text);
15+ _occ.shrink_to_fit ();
16+ }
17+
18+ ~RabinKarp () {}
19+
20+ void showOccurences () {
21+ // std::cout << __FUNCTION__ << std::endl;
22+ for (unsigned i : _occ)
23+ std::cout << i << " " ;
24+ std::cout << std::endl;
25+ }
26+
27+ std::vector<unsigned > const & getOccurences () {
28+ return _occ;
29+ }
30+ private:
31+ std::vector<unsigned > _occ;
32+ size_t _length;
33+ unsigned _patternHash;
34+ std::string _pattern;
35+
36+ void check (std::string const & str) {
37+ // std::cout << __FUNCTION__ << std::endl;
38+ size_t i = 1 ;
39+ long long newHash;
40+ long long oldHash;
41+ long long tmp;
42+ char newChar;
43+ char oldChar;
44+ size_t len = str.length () - _length + 1 ;
45+
46+ oldChar = str[0 ];
47+ oldHash = hash (str.c_str ());
48+ if (oldHash == _patternHash && equal (str, 0 ))
49+ _occ.push_back (0 );
50+ while (i < len) {
51+ newChar = str[i + _length -1 ];
52+ tmp = oldHash - oldChar;
53+ tmp = ((tmp % q) + q) %q;
54+ tmp /= x;
55+
56+ newHash = tmp + ( ((newChar * pow (x, _length - 1 ))%q) + q) % q;
57+ newHash %= q;
58+ std::cout << " i = " << i <<" ; oldChar = " << oldChar << " ; oldHash = " << oldHash
59+ << " ; newChar = " << newChar << " ; newHash " << newHash << " ; _patternHash: "
60+ << _patternHash << std::endl;
61+ if ( newHash == _patternHash && equal (str, i))
62+ _occ.push_back (i);
63+ oldHash = newHash;
64+ oldChar = str[i];
65+ ++i;
66+ }
67+ }
68+
69+ bool equal (std::string const & str, size_t index) {
70+ // std::cout << __FUNCTION__ << std::endl;
71+ size_t i = 0 ;
72+ while (i < _length) {
73+ if (_pattern[i] != str[index])
74+ return false ;
75+ ++index;
76+ ++i;
77+ }
78+ return true ;
79+ }
80+
81+ long long pow (long long base, size_t power) {
82+ // std::cout << __FUNCTION__ << std::endl;
83+ long long res = 1 ;
84+ if (power == 0 || base == 1 )
85+ return 1 ;
86+ for (size_t i = 0 ; i < power; ++i) {
87+ res *= base;
88+ res %= q;
89+ }
90+ return res;
91+ }
92+
93+ long long hash (char const * str) {
94+ // std::cout << __FUNCTION__ << std::endl;
95+ size_t i = 0 ;
96+ long long res = 0 ;
97+ long long tmp;
98+
99+ while (i < _length) {
100+ tmp = str[i] * pow (x, i);
101+ res += tmp %q;
102+ tmp = ((tmp%q) + q) %q;
103+ ++i;
104+ }
105+ res = ((res%q) + q)% q;
106+ return res;
107+ }
108+ };
109+
110+ int main (void )
111+ {
112+ std::string pattern;
113+ std::string text;
114+
115+ std::cin >> pattern >> text;
116+
117+ RabinKarp (pattern, text).showOccurences ();
118+
119+ return 0 ;
120+ }
0 commit comments