【发布时间】:2015-06-23 06:22:55
【问题描述】:
解决以下问题的好方法是什么?在命令式风格中,这可以在线性时间内完成。
给定两个排序序列p和q,f返回一个三元组序列r(或任何集合),其中r中的每个三元组(a,b,c),以下保持:
- (
abc) - 以下两项之一成立:
-
a,c是两个连续元素p,b在q -
a,c是两个连续元素q,b在p
-
示例:考虑以下两个序列。
val p = Seq(1,4,5,7,8,9)
val q = Seq(2,3,6,7,8,10)
然后f(p,s) 计算以下序列:
Seq((1,2,4), (1,3,4), (5,6,7), (3,4,6), (3,5,6), (8,9,10))
当前解决方案:我觉得这个不是很优雅。我正在寻找更好的。
def consecutiveTriplesOneWay(s1: Seq[Int], s2:Seq[Int]) = {
for {
i <- 0 until s1.size - 1 if s1(i) < s1(i+1)
j <- 0 until s2.size if s1(i) < s2(j) && s2(j) < s1(i+1)
} yield (s1(i), s2(j), s1(i+1))
}
def consecutiveTriples(s1: Seq[Int], s2:Seq[Int]) =
consecutiveTriplesOneWay(s1, s2) ++ consecutiveTriplesOneWay(s2, s1)
def main(args: Array[String]) {
val p = Seq(1,4,5,7,8,9)
val q = Seq(2,3,6,7,8,10)
consecutiveTriples(p, q).foreach(println(_))
}
编辑:我的命令式解决方案
def consecutiveTriplesOneWayImperative(s1: Seq[Int], s2:Seq[Int]) = {
var i = 0
var j = 0
val triples = mutable.MutableList.empty[(Int,Int,Int)]
while (i < s1.size - 1 && j < s2.size) {
if (s1(i) < s2(j) && s2(j) < s1(i + 1)) {
triples += ((s1(i), s2(j), s1(i + 1)))
j += 1
} else if (s1(i) >= s2(j))
j += 1
else
i += 1
}
triples.toSeq
}
def consecutiveTriples(s1: Seq[Int], s2:Seq[Int]) =
consecutiveTriplesOneWayImperative(s1,s2) ++
consecutiveTriplesOneWayImperative(s2,s1)
【问题讨论】:
-
你试过什么?函数式风格如何让翻译命令式解决方案变得困难?您是否使用过典型的 while -> fold/recurse 方法?
-
你有一些代码吗?因为这听起来像是一个练习,我们应该代替你解决它。
-
这看起来像家庭作业。如果这是用命令式编写的,用户应该注意到 (3, 5, 6) 缺少作为有效答案。
-
@Karl:感谢您发现错字。 :D 不是作业。大学毕业很久了。
-
我添加了我不太喜欢的当前解决方案。必须有一种更优雅的方式来做到这一点
标签: scala