这是我看到的代码看起来很丑,因为它使用了两个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
}
你如何以功能性的方式写这个?
答案 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