The Boyer-Moore string search algorithm is a fast and efficient algorithm for finding occurrences of a pattern within a string. It improves upon the naive string search approach by reducing the number of character comparisons needed to search for the pattern.
The algorithm works by first preprocessing the pattern to generate two tables, the "bad character" table and the "good suffix" table. The bad character table indicates the maximum shift distance for a given character in the pattern. The good suffix table indicates the maximum shift distance for a given suffix of the pattern.
When searching for the pattern within the string, the algorithm starts from the end of the pattern and compares the last character of the pattern with the corresponding character in the string. If there is a mismatch, the algorithm uses the bad character table to determine the maximum shift distance based on the last occurrence of the mismatched character in the pattern. If the character is not found in the pattern, the entire pattern can be shifted by the length of the pattern.
If the last character matches, the algorithm compares the second to last characters, and so on until the entire pattern is matched or a mismatch is found. If a mismatch is found, the algorithm uses the good suffix table to determine the maximum shift distance based on the longest matching suffix of the pattern.
Here is an example implementation of the Boyer-Moore algorithm in Java:
public static List<Integer> boyerMoore(String pattern, String text) {
List<Integer> matches = new ArrayList<>();
int n = text.length();
int m = pattern.length();
// preprocessing bad character table
int[] badChar = new int[256];
Arrays.fill(badChar, -1);
for (int i = 0; i < m; i++) {
badChar[pattern.charAt(i)] = i;
}
// preprocessing good suffix table
int[] goodSuffix = new int[m];
Arrays.fill(goodSuffix, m);
int i = m - 1;
int j = m - 2;
while (i >= 0 && j >= 0) {
if (pattern.charAt(i) == pattern.charAt(j)) {
goodSuffix[j] = i;
i--;
j--;
} else {
i = m - 1;
j--;
}
}
for (int k = 0; k < m - 1; k++) {
int r = m - 2 - k;
int shift = m - goodSuffix[r];
if (goodSuffix[r] != m && pattern.charAt(r) != pattern.charAt(m - 1)) {
shift = Math.max(shift, m - 1 - badChar[pattern.charAt(r)]);
}
goodSuffix[k] = shift;
}
// searching for matches
int k = m - 1;
while (k < n) {
int j = m - 1;
int i = k;
while (j >= 0 && text.charAt(i) == pattern.charAt(j)) {
i--;
j--;
}
if (j < 0) {
matches.add(i + 1);
k++;
} else {
int shift = Math.max(goodSuffix[j], j - badChar[text.charAt(i)]);
k += shift;
}
}
return matches;
}
Overall, the Boyer-Moore algorithm is a powerful and efficient string search algorithm that can greatly improve the performance of pattern searching in many applications.