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

2 Answers

0 votes
import scala.util.matching.Regex

object Main extends App {
  val s = "go java phphp rust c pphpp c++ phpphp python php phphp"

  def count(s: String, substr: String): Int = {
    val pattern: Regex = (s"$substr").r
    pattern.findAllIn(s).length
  }

  println(count(s, "php"))
}


/*
run:

6

*/

 



answered Aug 24, 2024 by avibootz
edited Jul 17 by avibootz
0 votes
object NonOverlappingCount {

  // 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.

  def countNonOverlapping(haystack: String, needle: String): Int = {
    /*
       Count how many times 'needle' appears in 'haystack' without overlapping.
       The algorithm:
         • Use .indexOf() 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.
    */

    var count = 0
    var index = 0 // current search position in the main string

    // Continue searching until .indexOf() returns -1 (meaning: no more matches)
    while ({
      // Find the next occurrence starting at the current index
      val pos = haystack.indexOf(needle, index)

      if (pos == -1) {
        // No more matches found
        false
      } else {
        // 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 = pos + needle.length

        true
      }
    }) ()
    
    count
  }


  // ---------------------------------------------------------------
  def main(args: Array[String]): Unit = {
    val s = "go java phphp rust c pphpp c++ phpphp python php phphp"
    val substring = "php"

    // Count non-overlapping occurrences
    val result = countNonOverlapping(s, substring)

    println(s"Non-overlapping occurrences: $result")
  }
}


/*
run:

Non-overlapping occurrences: 6

*/

 



answered Jul 17 by avibootz
edited Jul 18 by avibootz

Related questions

...