String Pattern Matching Naive in DSA C - Time & Space Complexity
We want to understand how the time needed to find a pattern in a text grows as the text and pattern get longer.
Specifically, how many steps does the naive search take when looking for a pattern inside a larger string?
Analyze the time complexity of the following code snippet.
int naiveSearch(char *text, char *pattern) {
int n = strlen(text);
int m = strlen(pattern);
for (int i = 0; i <= n - m; i++) {
int j;
for (j = 0; j < m; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == m)
return i; // pattern found at index i
}
return -1; // pattern not found
}
This code tries to find the first place where the pattern appears in the text by checking each possible position one by one.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The nested loops comparing characters of the pattern with the text.
- How many times: The outer loop runs about (n - m + 1) times, and for each, the inner loop runs up to m times.
As the text and pattern get longer, the number of comparisons grows roughly by multiplying their lengths.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 (text), 3 (pattern) | About 8 * 3 = 24 comparisons |
| 100 (text), 10 (pattern) | About 91 * 10 = 910 comparisons |
| 1000 (text), 50 (pattern) | About 951 * 50 = 47,550 comparisons |
Pattern observation: Doubling the text or pattern length roughly doubles or multiplies the work, showing a growth close to the product of their sizes.
Time Complexity: O(n * m)
This means the time to find the pattern grows roughly by multiplying the length of the text and the pattern.
[X] Wrong: "The search always takes time proportional to the text length only."
[OK] Correct: The pattern length matters too because for each position in the text, we may compare many characters of the pattern before deciding if it matches or not.
Understanding this simple search helps build a foundation for more efficient algorithms and shows you can analyze how nested loops affect performance.
"What if we changed the pattern to be very short, like a single character? How would the time complexity change?"
Practice
Solution
Step 1: Understand naive matching approach
The naive algorithm tries to match the pattern starting at each position in the text one by one.Step 2: Compare with other methods
Other methods like hashing or preprocessing are not part of the naive approach.Final Answer:
Check every possible position in the text to find the pattern -> Option AQuick Check:
Naive = Check all positions [OK]
- Confusing naive with hashing or preprocessing
- Thinking naive skips some positions
- Assuming sorting is involved
Solution
Step 1: Determine loop range for pattern matching
We must check positions where the pattern fits fully, so i goes from 0 to n - m inclusive.Step 2: Check options
for (int i = 0; i <= n - m; i++) correctly uses i <= n - m. Others either go beyond or do not cover all valid positions.Final Answer:
for (int i = 0; i <= n - m; i++) -> Option BQuick Check:
Loop till n - m inclusive [OK]
- Looping till n instead of n - m
- Using < instead of <= causing missed checks
- Looping only till m
char text[] = "abcabcabc";
char pattern[] = "abc";
int n = 9, m = 3;
int count = 0;
for (int i = 0; i <= n - m; i++) {
int j;
for (j = 0; j < m; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == m) count++;
}
printf("%d\n", count);Solution
Step 1: Identify pattern matches in text
Pattern "abc" appears at positions 0, 3, and 6 in the text "abcabcabc".Step 2: Count matches
Each match increments count, so total count is 3.Final Answer:
3 -> Option DQuick Check:
Pattern found 3 times [OK]
- Counting overlapping matches incorrectly
- Stopping after first match
- Off-by-one errors in loop
char text[] = "hellohello";
char pattern[] = "hello";
int n = 10, m = 5;
int count = 0;
for (int i = 0; i < n - m; i++) {
int j;
for (j = 0; j < m; j++) {
if (text[i + j] != pattern[j])
break;
}
if (j == m) count++;
}
printf("%d\n", count);Solution
Step 1: Analyze outer loop range
The loop runs from i = 0 to i < n - m, which misses the last valid position at i = n - m.Step 2: Fix loop condition
Changing to i <= n - m ensures all valid positions are checked.Final Answer:
Change loop condition to i <= n - m -> Option AQuick Check:
Loop must include last valid index [OK]
- Using < instead of <= in outer loop
- Changing inner loop incorrectly
- Misusing string functions for comparison
Solution
Step 1: Identify all starting positions for pattern
Text length n=8, pattern length m=3, so i from 0 to 5 inclusive.Step 2: Check matches including overlaps
Matches at positions 0 ("aba"), 2 ("aba"), and 4 ("aba") total 3 matches.Final Answer:
3 -> Option CQuick Check:
Count overlapping matches carefully [OK]
- Ignoring overlapping matches
- Counting only non-overlapping occurrences
- Off-by-one errors in loop range
Ready to prove it?
Pass the test and this pattern moves unknown
