Skip to content

Commit f2a5c1e

Browse files
author
Divyansh Saxena
committed
first commit
1 parent 11eec78 commit f2a5c1e

File tree

4 files changed

+74
-42
lines changed

4 files changed

+74
-42
lines changed

src/main/java/com/thealgorithms/strings/KMP.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.thealgorithms.strings;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
5+
36
/**
47
* Implementation of Knuth–Morris–Pratt algorithm Usage: see the main function
58
* for an example
@@ -8,16 +11,19 @@ public final class KMP {
811
private KMP() {
912
}
1013

11-
// a working example
12-
13-
public static void main(String[] args) {
14-
final String haystack = "AAAAABAAABA"; // This is the full string
15-
final String needle = "AAAA"; // This is the substring that we want to find
16-
kmpMatcher(haystack, needle);
17-
}
14+
/**
15+
* find the starting index in string haystack[] that matches the search word P[]
16+
*
17+
* @param haystack The text to be searched
18+
* @param needle The pattern to be searched for
19+
* @return A list of starting indices where the pattern is found
20+
*/
21+
public static List<Integer> kmpMatcher(final String haystack, final String needle) {
22+
List<Integer> occurrences = new ArrayList<>();
23+
if (haystack == null || needle == null || needle.isEmpty()) {
24+
return occurrences;
25+
}
1826

19-
// find the starting index in string haystack[] that matches the search word P[]
20-
public static void kmpMatcher(final String haystack, final String needle) {
2127
final int m = haystack.length();
2228
final int n = needle.length();
2329
final int[] pi = computePrefixFunction(needle);
@@ -32,10 +38,11 @@ public static void kmpMatcher(final String haystack, final String needle) {
3238
}
3339

3440
if (q == n) {
35-
System.out.println("Pattern starts: " + (i + 1 - n));
41+
occurrences.add(i + 1 - n);
3642
q = pi[q - 1];
3743
}
3844
}
45+
return occurrences;
3946
}
4047

4148
// return the prefix function
Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
11
package com.thealgorithms.strings;
22

3-
import java.util.Scanner;
3+
import java.util.ArrayList;
4+
import java.util.List;
45

56
/**
67
* @author Prateek Kumar Oraon (https://github.com/prateekKrOraon)
78
*
8-
An implementation of Rabin-Karp string matching algorithm
9-
Program will simply end if there is no match
9+
* An implementation of Rabin-Karp string matching algorithm
10+
* Program will simply end if there is no match
1011
*/
1112
public final class RabinKarp {
1213
private RabinKarp() {
1314
}
1415

15-
public static Scanner scanner = null;
16-
public static final int ALPHABET_SIZE = 256;
16+
private static final int ALPHABET_SIZE = 256;
1717

18-
public static void main(String[] args) {
19-
scanner = new Scanner(System.in);
20-
System.out.println("Enter String");
21-
String text = scanner.nextLine();
22-
System.out.println("Enter pattern");
23-
String pattern = scanner.nextLine();
24-
25-
int q = 101;
26-
searchPat(text, pattern, q);
18+
public static List<Integer> search(String text, String pattern) {
19+
return search(text, pattern, 101);
2720
}
2821

29-
private static void searchPat(String text, String pattern, int q) {
22+
public static List<Integer> search(String text, String pattern, int q) {
23+
List<Integer> occurrences = new ArrayList<>();
24+
if (text == null || pattern == null || pattern.isEmpty()) {
25+
return occurrences;
26+
}
27+
3028
int m = pattern.length();
3129
int n = text.length();
3230
int t = 0;
@@ -38,45 +36,30 @@ private static void searchPat(String text, String pattern, int q) {
3836
h = (int) Math.pow(ALPHABET_SIZE, m - 1) % q;
3937

4038
for (i = 0; i < m; i++) {
41-
// hash value is calculated for each character and then added with the hash value of the
42-
// next character for pattern as well as the text for length equal to the length of
43-
// pattern
4439
p = (ALPHABET_SIZE * p + pattern.charAt(i)) % q;
4540
t = (ALPHABET_SIZE * t + text.charAt(i)) % q;
4641
}
4742

4843
for (i = 0; i <= n - m; i++) {
49-
// if the calculated hash value of the pattern and text matches then
50-
// all the characters of the pattern is matched with the text of length equal to length
51-
// of the pattern if all matches then pattern exist in string if not then the hash value
52-
// of the first character of the text is subtracted and hash value of the next character
53-
// after the end of the evaluated characters is added
5444
if (p == t) {
55-
// if hash value matches then the individual characters are matched
5645
for (j = 0; j < m; j++) {
57-
// if not matched then break out of the loop
5846
if (text.charAt(i + j) != pattern.charAt(j)) {
5947
break;
6048
}
6149
}
6250

63-
// if all characters are matched then pattern exist in the string
6451
if (j == m) {
65-
System.out.println("Pattern found at index " + i);
52+
occurrences.add(i);
6653
}
6754
}
6855

69-
// if i<n-m then hash value of the first character of the text is subtracted and hash
70-
// value of the next character after the end of the evaluated characters is added to get
71-
// the hash value of the next window of characters in the text
7256
if (i < n - m) {
7357
t = (ALPHABET_SIZE * (t - text.charAt(i) * h) + text.charAt(i + m)) % q;
74-
75-
// if hash value becomes less than zero than q is added to make it positive
7658
if (t < 0) {
7759
t = (t + q);
7860
}
7961
}
8062
}
63+
return occurrences;
8164
}
8265
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.thealgorithms.strings;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import java.util.List;
5+
import org.junit.jupiter.api.Test;
6+
7+
public class KMPTest {
8+
9+
@Test
10+
public void testKMPMatcher() {
11+
assertEquals(List.of(0, 1), KMP.kmpMatcher("AAAAABAAABA", "AAAA"));
12+
assertEquals(List.of(0, 2), KMP.kmpMatcher("ABCABC", "ABC"));
13+
assertEquals(List.of(10), KMP.kmpMatcher("ABABDABACDABABCABAB", "ABABCABAB"));
14+
assertEquals(List.of(), KMP.kmpMatcher("ABCDE", "FGH"));
15+
assertEquals(List.of(), KMP.kmpMatcher("A", "AA"));
16+
assertEquals(List.of(0, 1, 2), KMP.kmpMatcher("AAA", "A"));
17+
assertEquals(List.of(0), KMP.kmpMatcher("A", "A"));
18+
assertEquals(List.of(), KMP.kmpMatcher("", "A"));
19+
assertEquals(List.of(), KMP.kmpMatcher("A", ""));
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.thealgorithms.strings;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import java.util.List;
5+
import org.junit.jupiter.api.Test;
6+
7+
public class RabinKarpTest {
8+
9+
@Test
10+
public void testRabinKarpSearch() {
11+
assertEquals(List.of(0, 1), RabinKarp.search("AAAAABAAABA", "AAAA"));
12+
assertEquals(List.of(0, 2), RabinKarp.search("ABCABC", "ABC"));
13+
assertEquals(List.of(10), RabinKarp.search("ABABDABACDABABCABAB", "ABABCABAB"));
14+
assertEquals(List.of(), RabinKarp.search("ABCDE", "FGH"));
15+
assertEquals(List.of(), RabinKarp.search("A", "AA"));
16+
assertEquals(List.of(0, 1, 2), RabinKarp.search("AAA", "A"));
17+
assertEquals(List.of(0), RabinKarp.search("A", "A"));
18+
assertEquals(List.of(), RabinKarp.search("", "A"));
19+
assertEquals(List.of(), RabinKarp.search("A", ""));
20+
}
21+
}

0 commit comments

Comments
 (0)