Scan for all matches in Ruby - Time & Space Complexity
We want to understand how long it takes to find all matches of a pattern in a string.
How does the time needed grow as the string gets longer?
Analyze the time complexity of the following code snippet.
text = "hello hello hello"
pattern = /hello/
matches = text.scan(pattern)
This code finds all occurrences of "hello" in the text string.
- Primary operation: The scan method checks each position in the string to see if the pattern matches.
- How many times: It repeats this check for almost every character in the string.
As the string gets longer, the number of checks grows roughly in direct proportion.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The work grows steadily as the string grows longer.
Time Complexity: O(n)
This means the time to find all matches grows in a straight line with the string length.
[X] Wrong: "The scan method only looks at the first few characters, so it's very fast regardless of string size."
[OK] Correct: Actually, scan checks the whole string to find all matches, so the time grows with the string length.
Understanding how searching through text grows with input size helps you explain efficiency clearly and confidently.
"What if the pattern was more complex, like a nested group or optional parts? How would the time complexity change?"
Practice
scan do when used on a string?Solution
Step 1: Understand the purpose of
Thescanscanmethod searches the string for all occurrences of a pattern.Step 2: Identify the return value of
It returns an array containing all matched parts of the string.scanFinal Answer:
It finds all matches of a pattern and returns them in an array. -> Option CQuick Check:
scanreturns matches array [OK]
- Confusing scan with gsub (replacement)
- Thinking scan returns a count
- Assuming scan modifies the original string
str using scan?Solution
Step 1: Recognize the correct regex syntax in Ruby
Ruby uses forward slashes/pattern/to denote regular expressions.Step 2: Identify the correct regex for digits
\d+matches one or more digits. The pattern must be inside slashes for regex.Final Answer:
str.scan(/\d+/) -> Option DQuick Check:
Regex in slashes with \d+ = str.scan(/\d+/) [OK]
- Using string quotes instead of regex slashes
- Missing escape backslash in regex
- Using incorrect regex delimiters
text = "cat bat rat" matches = text.scan(/.at/) puts matches.inspect
Solution
Step 1: Understand the regex
The dot/.at/.matches any single character, so.atmatches any three-letter word ending with 'at'.Step 2: Apply
The string "cat bat rat" contains "cat", "bat", and "rat" which all match the pattern.scanon the stringFinal Answer:
["cat", "bat", "rat"] -> Option BQuick Check:
scan finds all 3-letter words ending with 'at' [OK]
- Thinking dot matches zero or multiple chars
- Expecting partial matches like 'at' only
- Confusing scan output with string split
sentence. What is the error?
sentence = "apple banana apricot avocado"
words = sentence.scan("a\w+")
puts words.inspectSolution
Step 1: Check the argument type for
Thescanscanmethod expects a regex pattern, not a plain string.Step 2: Identify correct regex usage
The pattern should be written as/a\w+/to match words starting with 'a'.Final Answer:
The pattern should be a regex, not a string. -> Option AQuick Check:
scan requires regex pattern, not string [OK]
- Passing string instead of regex to scan
- Misunderstanding backslash escaping
- Assuming scan modifies the string
data = "log12 ID123, ID456, ID789", how can you use scan to extract only the numeric parts after each 'ID' (e.g., ["123", "456", "789"])?Solution
Step 1: Understand the pattern to extract numbers after 'ID'
The regex/ID(\d+)/matches 'ID' followed by digits, capturing only digits in parentheses. This ignores other digits like '12' in 'log12'.Step 2: Use
scanand flatten the resultscanreturns an array of arrays for capture groups, soflattenconverts it to a simple array of strings.Final Answer:
data.scan(/ID(\d+)/).flatten -> Option AQuick Check:
Capture group extracts digits, flatten simplifies array [OK]
- Using data.scan(/\d+/) which grabs all digits including extras like '12' and '78'
- Using scan without flatten, getting nested arrays
- Matching full 'ID123' instead of just digits
Ready to prove it?
Pass the test and this pattern moves unknown
