1

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

  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

4 回答 4

10

这很简单:

0.until(genome.length).filter(genome.startsWith(pattern, _))
于 2013-11-08T18:51:56.257 回答
2

你可以使用这样unfold的方法scalaz

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)
于 2013-11-08T12:18:15.763 回答
1

There is a much simpler idiomatic Scala solution that does not require trying to explicitly apply a pattern at every location or using 3rd party library:

def patternMatching(pattern: String, genome: String): List[Int] =
  pattern.r.findAllMatchIn(genome).map(_.start).toList
于 2018-02-23T09:31:38.707 回答
0

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

def patternMatchingIndex(pattern: Regex, text: String): List[(Int, Int)] =
  pattern.findAllMatchIn(text).map(index => (index.start, index.end)).toList
于 2018-06-02T02:01:59.637 回答