diff --git a/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java b/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java new file mode 100644 index 00000000..1da9bbc1 --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java @@ -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 diff --git a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java new file mode 100644 index 00000000..0bc0ab1f --- /dev/null +++ b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java @@ -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); + } + +}