📖 Scenario: You are building a simple text search tool that looks for a small word inside a larger text. This is like finding a word in a book by checking each page carefully.
🎯 Goal: Build a program that finds all starting positions where a given pattern appears in a text using the naive string matching method.
📋 What You'll Learn
Create a string variable text with the value "abracadabra".
Create a string variable pattern with the value "abra".
Create a vector variable positions to store all starting indices where pattern is found in text.
Use a for loop with variable i to check each possible starting index in text.
Use a nested for loop with variable j to compare characters of pattern with text.
If the pattern matches at index i, add i to positions.
Print the positions vector at the end.
💡 Why This Matters
🌍 Real World
Searching for keywords in documents, logs, or simple text files without advanced search tools.
💼 Career
Understanding basic string matching helps in text processing, search engines, and software debugging.
Progress0 / 4 steps
1
Create the text and pattern strings
Create a string variable text with the value "abracadabra" and a string variable pattern with the value "abra".
DSA Rust
Hint
Use let to create variables and assign the exact strings.
2
Create a vector to store matching positions
Create a mutable vector variable positions of type Vec<usize> to store the starting indices where pattern is found in text.
DSA Rust
Hint
Use let mut positions: Vec<usize> = Vec::new(); to create an empty vector.
3
Implement the naive pattern matching loops
Use a for loop with variable i from 0 to text.len() - pattern.len() inclusive. Inside it, use a nested for loop with variable j from 0 to pattern.len() to compare characters of pattern and text. If all characters match, push i into positions.
DSA Rust
Hint
Use text.as_bytes() and pattern.as_bytes() to compare characters by index.
4
Print the positions vector
Print the positions vector using println!("{:?}", positions); to display all starting indices where the pattern is found.
DSA Rust
Hint
Use println!("{:?}", positions); to print the vector.
Practice
(1/5)
1. What is the main idea behind the naive string pattern matching algorithm?
easy
A. Check every possible position in the text for the pattern
B. Use a hash function to find the pattern quickly
C. Build a prefix table to skip unnecessary checks
D. Sort the text and pattern before matching
Solution
Step 1: Understand naive matching approach
The naive algorithm tries to match the pattern starting at every position in the text.
Step 2: Compare with other methods
Other methods like hashing or prefix tables are not part of naive matching.
Final Answer:
Check every possible position in the text for the pattern -> Option A
Quick Check:
Naive = Check all positions [OK]
Hint: Naive means try all positions one by one [OK]
Common Mistakes:
Confusing naive with hashing or prefix methods
Thinking naive skips positions
Assuming sorting is involved
2. Which Rust code snippet correctly starts the naive pattern matching loop over text and pattern?
easy
A. for i in 0..text.len() + pattern.len() { /* check pattern */ }
B. for i in 0..=text.len() - pattern.len() { /* check pattern */ }
C. for i in 0..text.len() { /* check pattern */ }
D. for i in 0..pattern.len() { /* check pattern */ }
Solution
Step 1: Determine valid start positions
The pattern can only start at positions where it fits fully in the text, so from 0 to text length minus pattern length.
Step 2: Check Rust range syntax
Using 0..=text.len() - pattern.len() includes the last valid index.
Final Answer:
for i in 0..=text.len() - pattern.len() { /* check pattern */ } -> Option B
Quick Check:
Loop range = 0 to text.len()-pattern.len() [OK]
Hint: Loop till text length minus pattern length inclusive [OK]
3. What will be the output of this Rust code using naive pattern matching?
let text = "abracadabra";
let pattern = "abra";
let mut positions = Vec::new();
for i in 0..=text.len() - pattern.len() {
if &text[i..i+pattern.len()] == pattern {
positions.push(i);
}
}
println!("{:?}", positions);
medium
A. [3, 7]
B. [0, 3, 7]
C. [7]
D. [0, 7]
Solution
Step 1: Identify pattern matches in text
The pattern "abra" appears at index 0 ("abra") and index 7 ("abra") in "abracadabra".
Step 2: Confirm positions collected
Positions vector collects indices 0 and 7 where pattern matches exactly.
Final Answer:
[0, 7] -> Option D
Quick Check:
Matches at 0 and 7 only [OK]
Hint: Check substring slices equal to pattern [OK]
Common Mistakes:
Including partial matches like at index 3
Off-by-one errors in slicing
Missing second occurrence
4. Identify the bug in this naive pattern matching Rust code:
let text = "hello";
let pattern = "ll";
for i in 0..text.len() - pattern.len() {
if &text[i..i+pattern.len()] == pattern {
println!("Found at {}", i);
}
}
medium
A. Range should be 0..=text.len() - pattern.len() to include last position
B. Pattern length is used incorrectly in slicing
C. Text and pattern should be converted to chars before slicing
D. println! macro syntax is wrong
Solution
Step 1: Check loop range correctness
The loop uses 0..text.len() - pattern.len(), which excludes the last valid start index.
Step 2: Fix range to include last index
Using 0..=text.len() - pattern.len() includes the last position where pattern can start.
Final Answer:
Range should be 0..=text.len() - pattern.len() to include last position -> Option A
Quick Check:
Use inclusive range for last valid index [OK]
Hint: Use inclusive range to cover all valid start indices [OK]
Common Mistakes:
Using exclusive range causing missed matches
Incorrect slicing indices
Unnecessary conversion to chars
5. Given a text and a pattern, how can you modify the naive pattern matching to count overlapping occurrences of the pattern in Rust? Example: text = "aaaa", pattern = "aa" should count 3 occurrences.
hard
A. Increment index by pattern length after each match
B. Use a hash map to store counts
C. Increment index by 1 after each check instead of pattern length
D. Reverse the text and pattern before matching
Solution
Step 1: Understand overlapping matches
Overlapping means after finding a match, next check starts just one position ahead, not skipping full pattern length.
Step 2: Adjust loop increment
Increment index by 1 each time to allow overlapping matches to be found.
Final Answer:
Increment index by 1 after each check instead of pattern length -> Option C
Quick Check:
Step by 1 to count overlaps [OK]
Hint: Move index by 1 to catch overlaps [OK]
Common Mistakes:
Skipping by pattern length missing overlaps
Using hash map unnecessarily
Reversing strings does not help
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.