Skip to content

Commit 731b1bb

Browse files
committed
Add RabinKarp implementation
1 parent 7600231 commit 731b1bb

File tree

1 file changed

+57
-0
lines changed
  • src/main/java/com/packt/datastructuresandalg/lesson5/rabinkarp

1 file changed

+57
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.packt.datastructuresandalg.lesson5.rabinkarp;
2+
3+
import java.math.BigInteger;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.Random;
7+
8+
public class RabinKarp {
9+
public List<Integer> match(String P, String T) {
10+
// Good enough for ascii characters.
11+
int d = 256;
12+
int m = P.length();
13+
int n = T.length();
14+
long q = BigInteger.probablePrime(31, new Random()).longValue();
15+
16+
// Precompute d^(m-1) % q for use when removing leading digit
17+
long dm = 1;
18+
for (int i = 1; i <= m - 1; i++)
19+
dm = (d * dm) % q;
20+
21+
// Precompute p and t0
22+
long ph = 0;
23+
long th = 0;
24+
for (int i = 0; i < m; i++) {
25+
ph = (d * ph + P.charAt(i)) % q;
26+
th = (d * th + T.charAt(i)) % q;
27+
}
28+
29+
List<Integer> shifts = new ArrayList<>();
30+
for (int i = 0; i < n - m + 1; i++) {
31+
if (ph == th) {
32+
boolean hasMatch = true;
33+
for (int j = 0; j < m; j++) {
34+
if (P.charAt(j) != T.charAt(i + j)) {
35+
hasMatch = false;
36+
break;
37+
}
38+
}
39+
if (hasMatch)
40+
shifts.add(i);
41+
}
42+
43+
if (i + m < n) {
44+
th = (th + q - dm * T.charAt(i) % q) % q;
45+
th = (th * d + T.charAt(i + m)) % q;
46+
}
47+
}
48+
return shifts;
49+
}
50+
51+
public static void main(String[] args) {
52+
RabinKarp rk = new RabinKarp();
53+
List<Integer> matches = rk.match("rabrabracad", "abacadabrabracabracadabrabrabracad");
54+
for (Integer i : matches)
55+
System.out.println(i);
56+
}
57+
}

0 commit comments

Comments
 (0)