// Non‑overlapping occurrences are matches of a substring that do not reuse any of
// the same characters. Once one match is counted, the next search must begin
// after that match ends.
fn count_non_overlapping(haystack: &str, needle: &str) -> usize {
/*
Count how many times 'needle' appears in 'haystack' without overlapping.
The algorithm:
• Use .find() to locate the next occurrence.
• Each time a match is found, move the search index forward
by the full length of the matched substring.
• This ensures no characters are reused between matches.
*/
let mut count = 0;
let mut index = 0; // current search position in the main string
// Continue searching until .find() returns None (meaning: no more matches)
loop {
// Find the next occurrence starting at the current index
let pos = haystack[index..].find(needle);
match pos {
None => {
// No more matches found
break;
}
Some(p) => {
// We found a match, so increment the count
count += 1;
// Move index forward by the length of the needle
// This ensures the next search begins *after* the matched substring
index += p + needle.len();
}
}
}
count
}
// ---------------------------------------------------------------
fn main() {
// Demonstration using the string provided in the instructions:
let s = "go java phphp rust c pphpp c++ phpphp python php phphp";
let substring = "php";
// Count non-overlapping occurrences
let result = count_non_overlapping(s, substring);
println!("Non-overlapping occurrences: {}", result);
}
/*
run:
Non-overlapping occurrences: 6
*/