|
1 | 1 | package com.thealgorithms.searches;
|
2 | 2 |
|
3 |
| -// Following program is a Java implementation |
4 |
| -// of Rabin Karp Algorithm given in the CLRS book |
| 3 | +// Implementation of Rabin Karp Algorithm |
5 | 4 |
|
6 |
| -public class RabinKarpAlgorithm { |
| 5 | +public final class RabinKarpAlgorithm { |
| 6 | + private RabinKarpAlgorithm() { |
| 7 | + } |
7 | 8 |
|
8 | 9 | // d is the number of characters in the input alphabet
|
9 |
| - public static final int d = 256; |
| 10 | + private static final int d = 256; |
| 11 | + |
| 12 | + public static int search(String pattern, String text, int primeNumber) { |
10 | 13 |
|
11 |
| - /* pat -> pattern |
12 |
| - txt -> text |
13 |
| - q -> A prime number |
14 |
| - */ |
15 |
| - public int search(String pat, String txt, int q) { |
16 |
| - int index = -1; // note: -1 here represent not found, it is not an index |
17 |
| - int M = pat.length(); |
18 |
| - int N = txt.length(); |
19 |
| - int i, j; |
20 |
| - int p = 0; // hash value for pattern |
21 |
| - int t = 0; // hash value for txt |
| 14 | + int index = -1; // -1 here represents not found |
| 15 | + int patternLength = pattern.length(); |
| 16 | + int textLength = text.length(); |
| 17 | + int hashForPattern = 0; |
| 18 | + int hashForText = 0; |
22 | 19 | int h = 1;
|
23 | 20 |
|
24 |
| - // The value of h would be "pow(d, M-1)%q" |
25 |
| - for (i = 0; i < M - 1; i++) h = (h * d) % q; |
| 21 | + // The value of h would be "pow(d, patternLength-1)%primeNumber" |
| 22 | + for (int i = 0; i < patternLength - 1; i++) h = (h * d) % primeNumber; |
26 | 23 |
|
27 | 24 | // Calculate the hash value of pattern and first
|
28 | 25 | // window of text
|
29 |
| - for (i = 0; i < M; i++) { |
30 |
| - p = (d * p + pat.charAt(i)) % q; |
31 |
| - t = (d * t + txt.charAt(i)) % q; |
| 26 | + for (int i = 0; i < patternLength; i++) { |
| 27 | + hashForPattern = (d * hashForPattern + pattern.charAt(i)) % primeNumber; |
| 28 | + hashForText = (d * hashForText + text.charAt(i)) % primeNumber; |
32 | 29 | }
|
33 | 30 |
|
34 | 31 | // Slide the pattern over text one by one
|
35 |
| - for (i = 0; i <= N - M; i++) { |
36 |
| - // Check the hash values of current window of text |
37 |
| - // and pattern. If the hash values match then only |
38 |
| - // check for characters one by one |
39 |
| - if (p == t) { |
| 32 | + for (int i = 0; i <= textLength - patternLength; i++) { |
| 33 | + /* Check the hash values of current window of text |
| 34 | + and pattern. If the hash values match then only |
| 35 | + check for characters one by one*/ |
| 36 | + |
| 37 | + int j = 0; |
| 38 | + if (hashForPattern == hashForText) { |
40 | 39 | /* Check for characters one by one */
|
41 |
| - for (j = 0; j < M; j++) { |
42 |
| - if (txt.charAt(i + j) != pat.charAt(j)) break; |
| 40 | + for (j = 0; j < patternLength; j++) { |
| 41 | + if (text.charAt(i + j) != pattern.charAt(j)) break; |
43 | 42 | }
|
44 | 43 |
|
45 |
| - // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1] |
46 |
| - if (j == M) { |
47 |
| - System.out.println("Pattern found at index " + i); |
| 44 | + // if hashForPattern == hashForText and pattern[0...patternLength-1] = text[i, i+1, ...i+patternLength-1] |
| 45 | + if (j == patternLength) { |
48 | 46 | index = i;
|
49 | 47 | return index;
|
50 | 48 | }
|
51 | 49 | }
|
52 | 50 |
|
53 | 51 | // Calculate hash value for next window of text: Remove
|
54 | 52 | // leading digit, add trailing digit
|
55 |
| - if (i < N - M) { |
56 |
| - t = (d * (t - txt.charAt(i) * h) + txt.charAt(i + M)) % q; |
| 53 | + if (i < textLength - patternLength) { |
| 54 | + hashForText = (d * (hashForText - text.charAt(i) * h) + text.charAt(i + patternLength)) % primeNumber; |
57 | 55 |
|
58 |
| - // We might get negative value of t, converting it |
59 |
| - // to positive |
60 |
| - if (t < 0) t = (t + q); |
| 56 | + // handling negative hashForText |
| 57 | + if (hashForText < 0) hashForText = (hashForText + primeNumber); |
61 | 58 | }
|
62 | 59 | }
|
63 | 60 | return index; // return -1 if pattern does not found
|
|
0 commit comments