Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rabin Karp Algorithm added #1844

Merged
merged 1 commit into from
Jan 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion C-Plus-Plus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,5 +201,6 @@ _add list here_
- [Kth largest element](other/Kth_largest_element.cpp.cpp)
- [Kth smallest element](other/Kth_smallest_element.cpp)
- [Generate all Subsets](other/subsets.cpp)
- [Stock Span Problem](other/Stock_span_problem.cpp)
- [Boyer–Moore majority vote algorithm](other/majority_vote_algorithm.cpp)
- [Rabin Karp Algorithm (using rolling hash)](other/Rabin_Karp_Algorithm_using_rolling_hash.cpp)
- [Rabin Karp Algorithm (using prefix sum)](other/Rabin_Karp_Algorithm_using_prefix_sum.cpp)
123 changes: 123 additions & 0 deletions C-Plus-Plus/other/Rabin_Karp_Algorithm_using_prefix_sum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
Rabin Karp Algorithm (using prefix sum)
=========================================
Given a text and a pattern, find all the occurences of the pattern in the text

Time Complexity: O(n) n=size of string
Space Complexity: O(1)
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int mod = 1e9 + 7;
const int p = 31;

// returns (a^b)%mod
int powr(int a, int b) {
int ans = 1;
while (b) {
if (b & 1LL) {
ans *= a;
ans %= mod;
}
a *= a;
b = b >> 1;
a %= mod;
}
return ans % mod;
}

// returns (a^-1)%mod
int inv(int a) {
return powr(a, mod - 2) % mod;
}

// Assigns hash to a string
int polyHashString(string s) {
int hash = 0;
int coef = 1;
for (int i = 0; i < s.size(); i++) {
hash += (s[i] - 'a' + 1) * coef;
coef *= p;
coef %= mod;
hash %= mod;
}
return hash % mod;
}

// Rabin Karp Algorithm for pattern matching
// returns indices of pattern in string s
void rabinKarp(string s, string pat) {

int pat_hash = polyHashString(pat);
int n = s.size(), m = pat.size();

int pref[n] = {0};

for (int i = 0; i < n; i++) {
pref[i] = (s[i] - 'a' + 1) * powr(p, i);
pref[i] %= mod;
}

for (int i = 1; i < n; i++) {
pref[i] += pref[i - 1];
pref[i] %= mod;
}

bool patFound = 0;
for (int i = 0; i <= (n - m); i++) {
// substring from s[l.......r]
// r = i+m - 1
int l = i;
int r = i + m - 1;

int new_hash = pref[r];

if (i - 1 >= 0) {
new_hash -= pref[l - 1];
}

new_hash += mod; new_hash %= mod;

if (new_hash == (pat_hash * powr(p, l)) % mod) {
cout << i << endl;
patFound = 1;
}
}

if (!patFound) {
cout << "Not found";
}
}

// Driver Code
signed main() {

// Take input
string s, pat;
cin >> s >> pat;

rabinKarp(s, pat);
}

/*
Input:
ilovecoding
love

Output:
1

Input:
aaaaaaaa
aaa

Output:
0
1
2
3
4
5
*/
129 changes: 129 additions & 0 deletions C-Plus-Plus/other/Rabin_Karp_Algorithm_using_rolling_hash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
Rabin Karp Algorithm (using rolling hash)
=========================================
Given a text and a pattern, find all the occurences of the pattern in the text

Time Complexity: O(n) n=size of string
Space Complexity: O(1)
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int mod = 1e9 + 7;
const int p = 31;

// returns (a^b)%mod
int powr(int a, int b) {
int ans = 1;
while (b) {
if (b & 1LL) {
ans *= a;
ans %= mod;
}
a *= a;
b = b >> 1;
a %= mod;
}
return ans % mod;
}

// returns (a^-1)%mod
int inv(int a) {
return powr(a, mod - 2) % mod;
}

// Assigns hash to a string
int polyHashString(string s) {
int hash = 0;
int coef = 1;
for (int i = 0; i < s.size(); i++) {
hash += (s[i] - 'a' + 1) * coef;
coef *= p;
coef %= mod;
hash %= mod;
}
return hash % mod;
}

// Rabin Karp Algorithm for pattern matching
// returns indices of pattern in string s
void rabinKarp(string s, string pat) {

int n = s.size();
int m = pat.size();

int patHash = polyHashString(pat);
// Maintains hash of current window of size m
int currHash = polyHashString(s.substr(0, m));

bool patFound = 0;

// If first window matches pattern
if (currHash == patHash) {
cout << 0 << endl;
patFound = 1;
}

// coefficient for next character
int coef = powr(p, m - 1);

for (int i = 1; i <= (n - m); i++) {
int newHash = currHash;

// Subtract previous character
newHash -= s[i - 1] - 'a' + 1;
newHash += mod; newHash %= mod;

// divide by prime
newHash *= inv(p);
newHash %= mod;

// Add next char
newHash += (s[i + m - 1] - 'a' + 1) * coef;
newHash %= mod;

// Check
if (newHash == patHash) {
cout << i << endl;
patFound = 1;
}

currHash = newHash;
}

if (!patFound) {
cout << "Not found";
}
}

// Driver Code
signed main() {

// Take input
string s, pat;
cin >> s >> pat;

rabinKarp(s, pat);
}

/*
Input:
ilovecoding
love

Output:
1

Input:
aaaaaaaa
aaa

Output:
0
1
2
3
4
5
*/