在字符串中查找模式的所有索引?

时间:2013-11-08 12:00:08

标签: scala functional-programming

这是我看到的代码看起来很丑,因为它使用了两个vars。

  def patternMatching(pattern: String, genome: String): List[Int] = {
    assert(pattern.length < genome.length)
    var curr = 0
    var r = List[Int]()
    while (curr != -1) {
      curr = genome.indexOf(pattern, curr)
      if (curr != -1) {
        r ::= curr
        curr += 1
      }
    }
    r.reverse
  }

你如何以功能性的方式写这个?

4 个答案:

答案 0 :(得分:9)

这是非常困难的:

0.until(genome.length).filter(genome.startsWith(pattern, _))

答案 1 :(得分:2)

您可以使用scalaz中的unfold方法,如下所示:

import scalaz._, Scalaz._

def patternIndexes(pattern: String, genome: String) = unfold(0){
  genome.indexOf(pattern, _) match {
    case -1 => None
    case n => (n, n+1).some
  }
}

用法:

scala> patternIndexes("a", "aba").toList
res0: List[Int] = List(0, 2)

答案 2 :(得分:0)

有一个更简单的惯用Scala解决方案,不需要尝试在每个位置或使用第三方库明确应用模式:

def patternMatching(pattern: String, genome: String): List[Int] =
  pattern.r.findAllMatchIn(genome).map(_.start).toList

答案 3 :(得分:0)

如果您还需要知道索引的结束位置,您可以使用:

def patternMatchingIndex(pattern: Regex, text: String): List[(Int, Int)] =
  pattern.findAllMatchIn(text).map(index => (index.start, index.end)).toList