The Boyer-Moore Algorithm: How the Bad Character and Good Suffix Rules Achieve Sublinear String Searching
By comparing text from right to left and utilizing two distinct skipping rules, the Boyer-Moore algorithm allows search functions to bypass characters entirely, making it faster as the search term gets longer.
By Nabil Faris
- Theoretical Computer Scientists
- Focus on the algorithm's mathematical bounds, proving its worst-case and best-case time complexities.
- Systems Programmers
- Value the algorithm for its practical implementation in standard libraries, text editors, and command-line tools.
- Bioinformaticians
- Highlight the algorithm's limitations when searching through small alphabets, such as four-letter DNA sequences.
Perspectives this story doesn't cover
- Hardware designers optimizing search at the silicon level
In October 1977, computer scientists Robert S. Boyer and J Strother Moore published a paper in the Communications of the ACM that inverted how computers search for text. Prior to their work, finding a specific word inside a larger document required a naive approach: the computer would check the first letter, and if it matched, check the second. If a mismatch occurred, the search pattern shifted forward by exactly one character, and the process started over. This meant that searching for a 10-character word in a 1,000-character text could require up to 10,000 individual comparisons in the worst-case scenario.[6]
Boyer and Moore realized that reading from left to right was fundamentally inefficient. Their algorithm aligns the search pattern with the text, but instead of checking the first character, it checks the last. If the last character of the pattern does not match the text character it aligns with, the algorithm gains immediate, actionable information about how far it can safely jump forward without missing a potential match.[4][6]
To achieve these massive jumps, the algorithm relies on a preliminary step before the search even begins. As software engineer Sam Spilsbury notes, "The algorithm preprocesses the string being searched for (the pattern), but not the string being searched in (the text)." By analyzing the search term in advance, the program builds two distinct lookup tables—one for the Bad Character rule and one for the Good Suffix rule. These tables dictate exactly how many spaces the pattern can shift when a mismatch inevitably occurs.[1]
The Bad Character rule is the first heuristic. When the algorithm compares the pattern against the text from right to left and finds a mismatch, it looks at the offending character in the main text. If that specific character does not exist anywhere in the search pattern, the algorithm knows that no match can possibly overlap with that position. It immediately shifts the entire pattern past that character. If the pattern is seven letters long, a single mismatch can trigger a seven-character jump, bypassing the intermediate text entirely.[3][4]
However, if the mismatched text character does exist elsewhere in the search pattern, the Bad Character rule shifts the pattern just enough to align the rightmost occurrence of that character in the pattern with the mismatched character in the text. This ensures the algorithm never skips over a valid match, but it still often results in a multi-character leap rather than a single-space crawl.[3][5]
The Bad Character rule alone is powerful, but it has a vulnerability. If the mismatched character appears very close to the end of the search pattern, the resulting shift might be negligible, or in some edge cases, it could theoretically suggest a negative shift. To prevent the search from stalling, Boyer and Moore introduced a second, parallel heuristic: the Good Suffix rule.[2][6]
The Bad Character rule alone is powerful, but it has a vulnerability.
The Good Suffix rule activates when the algorithm has successfully matched a few characters at the end of the pattern (the "good suffix") before hitting a mismatch further left. Because the algorithm has already verified that this specific sequence of characters exists in the text, it consults its preprocessed table to find the next occurrence of that exact sequence earlier in the search pattern. It then shifts the pattern forward to align that earlier occurrence with the matched text.[2][5]
If the matched suffix does not appear anywhere else in the pattern, the algorithm checks if a prefix of the pattern matches a suffix of the already-matched text. If it does, it shifts the pattern to align them. If neither condition is met, the algorithm knows the entire matched suffix cannot be part of a valid overlapping match, and it shifts the pattern completely past the matched section.[2][6]
During execution, the Boyer-Moore algorithm calculates the recommended shift from both the Bad Character rule and the Good Suffix rule at every mismatch. It then simply takes the larger of the two numbers. This dual-heuristic approach guarantees that the algorithm is always making the most aggressive safe jump possible through the document.[5][6]
This aggressive skipping leads to a counterintuitive performance metric: sublinear time complexity. In computer science, an algorithm that reads every character once operates in linear time, denoted as O(n). Because Boyer-Moore skips characters, its best-case performance is O(n/m), where 'n' is the length of the text and 'm' is the length of the pattern. The longer the word you are searching for, the faster the algorithm finishes, because a longer pattern allows for longer jumps.[1][6]
The efficiency of Boyer-Moore made it the foundational logic for standard search utilities. When a developer uses the GNU `grep` command to parse gigabytes of server logs, or a user searches a massive PDF, the underlying engine is frequently a variant of Boyer-Moore. Its ability to process text faster than the computer can sequentially read it from memory cemented its status as a benchmark in string-matching literature.[1][6]
The algorithm does face limitations depending on the dataset. In a standard English text using the 256-character ASCII alphabet, the Bad Character rule triggers massive shifts constantly because most characters in the text won't appear in a short search pattern. However, in bioinformatics, where DNA sequences consist of only four letters (A, C, G, T), the Bad Character rule degrades. The mismatched character is almost always present in the pattern, resulting in very short shifts.[3][6]
To address these edge cases, later computer scientists developed variations. The Boyer-Moore-Horspool algorithm, published in 1980, simplified the logic by dropping the Good Suffix rule entirely, relying on a slightly modified Bad Character rule that performs better in average-case scenarios with large alphabets. The Apostolico-Giancarlo algorithm later optimized the Good Suffix rule to prevent redundant comparisons when the pattern shifts.[6]
Nearly 50 years after its publication, the core insight of Boyer and Moore remains intact. By spending a fraction of a millisecond analyzing the search term before looking at the document, and by reading backwards to move forwards, software avoids doing unnecessary work. The algorithm dictates that the fastest way to find a needle in a haystack is to know exactly which parts of the hay to ignore.
Key points
- The Boyer-Moore algorithm searches for text by aligning the pattern and comparing characters from right to left.
- The Bad Character rule skips ahead when a mismatched text character does not appear in the search pattern.
- The Good Suffix rule calculates jumps based on sections of the pattern that have already successfully matched.
- The algorithm achieves sublinear time complexity, meaning it gets faster as the search term gets longer.
Key terms
- Sublinear Time
- An execution speed where an algorithm processes a dataset without having to inspect every single element within it.
- Preprocessing
- An initial step where the algorithm analyzes the search pattern to build lookup tables before it begins scanning the main text.
- Heuristic
- A rule-of-thumb strategy used by an algorithm to make decisions, such as calculating how far to jump after a mismatch.
- Time Complexity
- A theoretical measure of how the runtime of an algorithm increases as the size of the input data grows.
Sources
[1]Sam SpilsburySystems ProgrammersExplaining Boyer-Moore
Read on Sam Spilsbury →
[2]HyperskillBioinformaticiansBoyer-Moore: Good suffix rule
Read on Hyperskill →
[3]HyperskillBioinformaticiansBoyer-Moore: Bad character rule
Read on Hyperskill →
[4]Emory CSTheoretical Computer ScientistsA Simplified Boyer-Moore Algorithm
Read on Emory CS →
[5]OpenDSATheoretical Computer Scientists5.3. Boyer-Moore String Search Algorithm
Read on OpenDSA →
[6]WikipediaTheoretical Computer ScientistsBoyer–Moore string-search algorithm
Read on Wikipedia →
[7]Factlen Editorial TeamSystems ProgrammersSynthesis by Factlen editorial team
Read on Factlen Editorial Team →
Comments
More in Guides
See all →Bond Duration
Macaulay Duration vs. Modified Duration: How Time and Price Sensitivity Differ
4 sources
ADA Compliance
The 50-Foot Rule and the 10% Slope: How the ADA Defines an Accessible Ramp
2 sources
Password Security
How Hashing and Salting Secure Passwords by Preventing Rainbow Table Attacks
8 sources
Product Passports
The EU's Digital Product Passport: A Guide to the New Product-Level Transparency Mandate and the ESPR
4 sources
Every angle. Every day.
Get Guides stories with full source coverage and perspective breakdowns delivered to your inbox.




