How to count the number of non-overlapping instances of a substring in a string in Rust

1 Answer

0 votes
// 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

*/

 



answered Aug 24, 2024 by avibootz
edited 6 hours ago by avibootz

Related questions

...