Repository: TheAlgorithms/Java
Pull request #3201 (2022-07-30 16:43:21)

Create a new Rabin-Karp Algorithm
This is a Rabin-Karp Algorithm for Pattern Searching

### **Describe your change:**

- [x] Add an algorithm?
- [ ] Fix a bug or typo in an existing algorithm?
- [ ] Documentation change?

#### References

[Rabin–Karp algorithm](https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm)


### **Checklist:**


- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] I know that pull requests will not be merged if they fail the automated tests.
- [x] This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
- [x] All new Java files are placed inside an existing directory.
- [x] All filenames are in all uppercase characters with no spaces or dashes.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in its comments that points to Wikipedia or other similar explanation.


tackhwa: > The code looks good, could you just replace `main()` with a couple of JUnit tests and add the `.java` extension to the file? See examples of tests in src/test/

I have already added the JUnit test case and '.java' extension, please take your time to review, Thank You.
tackhwa: I have already resolved the issue, please take your time to review it, thank you.

Patch:
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


Test patch:
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);
+    }
+
+}