Skip to content

Commit 6d8bb42

Browse files
William FisetWilliam Fiset
William Fiset
authored and
William Fiset
committed
Boyer-Moore minor optimizations
1 parent 5ff004e commit 6d8bb42

File tree

1 file changed

+28
-18
lines changed

1 file changed

+28
-18
lines changed
Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1+
/**
2+
* Performs Boyer-Moore search on a given string with a given pattern
3+
*
4+
* <p>./gradlew run -Palgorithm=strings.BoyerMooreStringSearch
5+
*/
16
package com.williamfiset.algorithms.strings;
27

8+
import static java.lang.Math.max;
9+
import static java.lang.Math.min;
310
import static java.util.Objects.isNull;
411

512
import java.util.ArrayList;
6-
import java.util.HashMap;
713
import java.util.List;
8-
import java.util.Map;
914

1015
public class BoyerMooreStringSearch {
1116

17+
private static final int MAX_ALPHABET_SIZE = 256;
18+
1219
/**
1320
* Performs Boyer-Moore search on a given string with a given pattern
1421
*
@@ -24,11 +31,10 @@ public List<Integer> findOccurrences(String text, String pattern) {
2431
return new ArrayList<>();
2532
}
2633
List<Integer> occurrences = new ArrayList<>();
27-
Map<Character, Integer> skipTable = generateSkipTable(pattern);
34+
int[] skipTable = generateSkipTable(pattern);
2835

29-
int textIndex = pattern.length() - 1;
30-
int patternIndex = pattern.length() - 1;
31-
while (textIndex < text.length()) {
36+
int n = pattern.length();
37+
for (int textIndex = n - 1, patternIndex = n - 1; textIndex < text.length(); ) {
3238
if (patternIndex >= 0 && pattern.charAt(patternIndex) == text.charAt(textIndex)) {
3339
if (patternIndex == 0) {
3440
occurrences.add(textIndex);
@@ -37,23 +43,27 @@ public List<Integer> findOccurrences(String text, String pattern) {
3743
}
3844
patternIndex--;
3945
} else {
40-
textIndex =
41-
textIndex
42-
+ pattern.length()
43-
- Math.min(
44-
Math.max(patternIndex, 0),
45-
1 + skipTable.getOrDefault(text.charAt(textIndex), 0));
46-
patternIndex = pattern.length() - 1;
46+
textIndex += n - min(max(patternIndex, 0), 1 + skipTable[text.charAt(textIndex)]);
47+
patternIndex = n - 1;
4748
}
4849
}
4950
return occurrences;
5051
}
5152

52-
private Map<Character, Integer> generateSkipTable(String pattern) {
53-
Map<Character, Integer> characterIndexMap = new HashMap<>();
54-
for (int charIndex = 0; charIndex < pattern.length(); charIndex++) {
55-
characterIndexMap.put(pattern.charAt(charIndex), charIndex);
53+
private int[] generateSkipTable(String pattern) {
54+
int[] skipTable = new int[MAX_ALPHABET_SIZE];
55+
for (int i = 0; i < pattern.length(); i++) {
56+
skipTable[(int) pattern.charAt(i)] = i;
5657
}
57-
return characterIndexMap;
58+
return skipTable;
59+
}
60+
61+
public static void main(String[] args) {
62+
BoyerMooreStringSearch searcher = new BoyerMooreStringSearch();
63+
String t = "ABABAAABAABAB";
64+
String p = "AA";
65+
66+
// Prints: [4, 5, 8]
67+
System.out.println(searcher.findOccurrences(t, p));
5868
}
5969
}

0 commit comments

Comments
 (0)