Add Rabin-Karp String Search Algorithm (#3201)
This commit is contained in:
parent
965c20381c
commit
92bd9ba3c9
@ -0,0 +1,77 @@
|
||||
package com.thealgorithms.searches;
|
||||
// Following program is a Java implementation
|
||||
// of Rabin Karp Algorithm given in the CLRS book
|
||||
|
||||
public class RabinKarpAlgorithm
|
||||
{
|
||||
// d is the number of characters in the input alphabet
|
||||
public final static int d = 256;
|
||||
|
||||
/* pat -> pattern
|
||||
txt -> text
|
||||
q -> A prime number
|
||||
*/
|
||||
public int search(String pat, String txt, int q)
|
||||
{
|
||||
int index = -1; //note: -1 here represent not found, it is not an index
|
||||
int M = pat.length();
|
||||
int N = txt.length();
|
||||
int i, j;
|
||||
int p = 0; // hash value for pattern
|
||||
int t = 0; // hash value for txt
|
||||
int h = 1;
|
||||
|
||||
// The value of h would be "pow(d, M-1)%q"
|
||||
for (i = 0; i < M-1; i++)
|
||||
h = (h*d)%q;
|
||||
|
||||
// Calculate the hash value of pattern and first
|
||||
// window of text
|
||||
for (i = 0; i < M; i++)
|
||||
{
|
||||
p = (d*p + pat.charAt(i))%q;
|
||||
t = (d*t + txt.charAt(i))%q;
|
||||
}
|
||||
|
||||
// Slide the pattern over text one by one
|
||||
for (i = 0; i <= N - M; i++)
|
||||
{
|
||||
|
||||
// Check the hash values of current window of text
|
||||
// and pattern. If the hash values match then only
|
||||
// check for characters one by one
|
||||
if ( p == t )
|
||||
{
|
||||
/* Check for characters one by one */
|
||||
for (j = 0; j < M; j++)
|
||||
{
|
||||
if (txt.charAt(i+j) != pat.charAt(j))
|
||||
break;
|
||||
}
|
||||
|
||||
// if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
|
||||
if (j == M) {
|
||||
System.out.println("Pattern found at index " + i);
|
||||
index= i;
|
||||
return index ;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate hash value for next window of text: Remove
|
||||
// leading digit, add trailing digit
|
||||
if ( i < N-M )
|
||||
{
|
||||
t = (d*(t - txt.charAt(i)*h) + txt.charAt(i+M))%q;
|
||||
|
||||
// We might get negative value of t, converting it
|
||||
// to positive
|
||||
if (t < 0)
|
||||
t = (t + q);
|
||||
}
|
||||
}
|
||||
return index; // return -1 if pattern does not found
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// This code is contributed by nuclode
|
@ -0,0 +1,58 @@
|
||||
package com.thealgorithms.searches;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
class RabinKarpAlgorithmTest {
|
||||
|
||||
|
||||
RabinKarpAlgorithm RKA= new RabinKarpAlgorithm();
|
||||
int q= 101;
|
||||
|
||||
@Test
|
||||
// valid test case
|
||||
public void RabinKarpAlgorithmTestExample() {
|
||||
String txt = "This is an example for rabin karp algorithmn";
|
||||
String pat = "algorithmn";
|
||||
int value = RKA.search(pat, txt, q);
|
||||
assertEquals(value,34);
|
||||
}
|
||||
|
||||
@Test
|
||||
// valid test case
|
||||
public void RabinKarpAlgorithmTestFront() {
|
||||
String txt = "AAABBDDG";
|
||||
String pat = "AAA";
|
||||
int value = RKA.search(pat, txt, q);
|
||||
assertEquals(value, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
// valid test case
|
||||
public void RabinKarpAlgorithmTestMiddle() {
|
||||
String txt = "AAABBCCBB";
|
||||
String pat = "BBCC";
|
||||
int value = RKA.search(pat, txt, q);
|
||||
assertEquals(value, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
// valid test case
|
||||
public void RabinKarpAlgorithmTestLast() {
|
||||
String txt = "AAAABBBBCCC";
|
||||
String pat = "CCC";
|
||||
int value = RKA.search(pat, txt, q);
|
||||
assertEquals(value, 8);
|
||||
}
|
||||
|
||||
@Test
|
||||
// valid test case
|
||||
public void RabinKarpAlgorithmTestNotFound() {
|
||||
String txt = "ABCBCBCAAB";
|
||||
String pat = "AADB";
|
||||
int value = RKA.search(pat, txt, q);
|
||||
assertEquals(value, -1);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user