这是我的伪代码,显然这不是惯用的scala,因为我使用了很多可变变量和循环。
我的目标是以功能的方式将其转换为惯用的scala。
算法的目标是给定一个字符串列表,对其自身进行N ^ 2比较,以使用编辑距离查找匹配。因为编辑距离检查是示例,所以我想避免对已检查的字符串对进行编辑距离检查。
def pairwisecomp(block: Iterable[String]): List[(String, String)] = {
var matches = new ListBuffer[(String, String)]
// pseudo code; not intended to be valid scala
for (var i = 0; i < block.size; i++) {
val str1 = block[i]
// iterate from i because no need to go backwards to compare
for (var j = i+1; j < block.size; j++) {
val str2 = block[j]
// check edit distance
// if less than 2, append into the matches
if (editDistance(str1, str2) < 2) {
matches.append((str1, str2))
}
}
}
return matches.toList
}
答案 0 :(得分:3)
我认为它可以缩短,我认为代码的打击与你写的完全相同。
NULL
编辑: 在理解方面可能更简单。
block.flatMap{ str1 =>
block.zipWithIndex.filter{ case (elem,index) => index > i}.map{ case (str2,index) =>
((str1,str2),editDistance(str1,str2) < 2)
}.filter{_.2}.map{_1}
}.toList
答案 1 :(得分:1)
如果没有工作editDistance()
来测试它很难知道,但我认为这与你所追求的很接近。
def pairwisecomp(block: Seq[String]): List[List[String]] = {
block.combinations(2).filter(editDistance(str1, str2) < 2).toList
}
请注意,我更改了block
集合类型,以便我可以使用combinations()
方法。还有其他方法可以实现这一目标。
答案 2 :(得分:1)
'tails'是你的朋友:
def tryIt(): Unit = {
def editDistance(v1: (String, Int), v2: (String, Int)): Int = {
val (_, d1) = v1
val (_, d2) = v2
Math.abs(d1-d2)
}
val src = Seq (("C", 3), ("D", 4), ("A", 1), ("B", 2), ("E", 5), ("F", 6))
val res = for {
(h::tl) <- src.tails
t <- tl if editDistance(h ,t) < 2
} yield (h,t)
res.foreach {case (r1, r2) => println(s"$r1, $r2")}
}
(h :: tl)是输入中的每个元素(h)的系列加上它后面的所有内容(tl)。从那里你比较尾部序列tl中的每个元素't'。如果'h'和't'足够接近,则产生该对。
答案 3 :(得分:0)
我认为你可以使用for-comprehension:
def pairwisecompII(block: Vector[String]): Seq[(String, String)] = {
for {
i ← block.indices
str1 = block(i)
j ← i + 1 until block.size
str2 = block(j)
if editDistance(str1, str2) < 2
} yield (str1, str2)
}