Here we present the Brute Force algorithm that solves the Exact String Matching problem.
The brute force approach to string matching is the most direct and intuitive method for finding a pattern \( P \) of length \( m \) within a text \( T \) of length \( n \). It systematically checks every possible starting position in the text where the pattern could begin and compares characters one-by-one.
At each shift position \( i \), the algorithm checks whether \( T[i..i+m-1] = P[0..m-1] \). That is, if characters \(i\) through \(i+m-1\) in the text all match, character by character, the characters of the pattern. If all characters match, then a match is found. Otherwise, it shifts the pattern by one position and tries again.
Here is a formal description of the algorithm:
Text: A B C A D A B C A A B i=0: A B C i=1: A B C i=2: A B C i=3: A B C i=4: A B C i=5: A B C i=6: A B C i=7: A B C i=8: A B C
This algorithm exemplifies the brute force technique because it tries every possibility without using any preprocessing or insight about the pattern or text to eliminate unnecessary comparisons.
Try the following demo with several different patterns and texts to make sure you understand exactly what the algorithm is doing.
This is the straightforward version of brute-force string matching in three languages.
The Java version assumes the text and pattern are stored as Strings,
C++ is using std:string, and Python is using the str type.
All three implementations find all matches.
void bruteForceMatch(String text, String pattern) {
int n = text.length();
int m = pattern.length();
for (int i = 0; i <= n - m; i++) {
int j = 0;
while (j < m && text.charAt(i + j) == pattern.charAt(j)) {
j++;
}
if (j == m) {
System.out.println("Match at index " + i);
}
}
}
void bruteForceMatch(string text, string pattern) {
int n = text.size();
int m = pattern.size();
for (int i = 0; i <= n - m; i++) {
int j = 0;
while (j < m && text[i + j] == pattern[j]) {
j++;
}
if (j == m) {
cout << "Match at index " << i << endl;
}
}
}
def brute_force_match(text, pattern):
n, m = len(text), len(pattern)
for i in range(n - m + 1):
j = 0
while j < m and text[i + j] == pattern[j]:
j += 1
if j == m:
print(f"Match at index {i}")
Time Complexity: In the worst case, for each of the \( n - m + 1 \) positions, we may perform up to \( m \) comparisons. Therefore, the worst-case time is \( O((n - m + 1)m) = O(nm) \). This occurs, for example, when both the pattern and text contain repeated characters and nearly match at each position.
The best case occurs when an early mismatch happens at each position, leading to \( O(n) \) total comparisons.
Space Complexity: The algorithm uses \( O(1) \) extra space. It does not use any auxiliary arrays or recursion.