Skip to content

Commit b597392

Browse files
committed
Add KnuthMorrisPratt.java (KMP)
1 parent 0f9139d commit b597392

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.thealgorithms.strings;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
7+
final class KnuthMorrisPratt {
8+
private KnuthMorrisPratt() {
9+
}
10+
11+
// Compute the longest proper prefix which is also suffix (LPS) array
12+
public static int[] computeLps(final String pattern) {
13+
final int n = pattern.length();
14+
final int[] lps = new int[n];
15+
int len = 0; // length of the previous longest prefix suffix
16+
lps[0] = 0;
17+
for (int i = 1; i < n; ) {
18+
if (pattern.charAt(i) == pattern.charAt(len)) {
19+
len++;
20+
lps[i] = len;
21+
i++;
22+
} else {
23+
if (len != 0) {
24+
len = lps[len - 1];
25+
} else {
26+
lps[i] = 0;
27+
i++;
28+
}
29+
}
30+
}
31+
return lps;
32+
}
33+
34+
// Return list of start indices where pattern occurs in text
35+
public static List<Integer> search(final String text, final String pattern) {
36+
final List<Integer> occurrences = new ArrayList<>();
37+
if (pattern == null || pattern.isEmpty() || text == null) {
38+
return occurrences;
39+
}
40+
41+
final int[] lps = computeLps(pattern);
42+
int i = 0; // index for text
43+
int j = 0; // index for pattern
44+
final int n = text.length();
45+
final int m = pattern.length();
46+
while (i < n) {
47+
if (text.charAt(i) == pattern.charAt(j)) {
48+
i++;
49+
j++;
50+
if (j == m) {
51+
occurrences.add(i - j);
52+
j = lps[j - 1];
53+
}
54+
} else {
55+
if (j != 0) {
56+
j = lps[j - 1];
57+
} else {
58+
i++;
59+
}
60+
}
61+
}
62+
return occurrences;
63+
}
64+
65+
// example runner
66+
public static void main(String[] args) {
67+
final String text = "AAAAABAAABA";
68+
final String pattern = "AAAA";
69+
final List<Integer> idx = search(text, pattern);
70+
for (int pos : idx) {
71+
System.out.println("Pattern starts: " + pos);
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)