通过逐步修改scala列表来构建它。什么是最有效的“添加”运算符?在CPU和资源消耗方面。
例如,从List(1,2,3)我们想要创建一个连续数字元组的列表。结果如下:List((1,2),(2,3))
方法1 - 使用:+运算符
def createConsecutiveNumPair1[T](inList: List[T]) : List[(T, T)] = {
var listResult = List[(T, T)]()
var prev = inList(0)
for (curr <- inList.tail)
{
listResult = listResult :+ (prev, curr)
prev = curr
}
listResult
}
方法2 - 使用:: =运算符
def createConsecutiveNumPair2[T](inList: List[T]) : List[(T, T)] = {
var listResult = List[(T, T)]()
var prev = inList(0)
for (curr <- inList.tail)
{
listResult ::= (prev, curr)
prev = curr
}
listResult
}
TEST
scala> val l1 = List(1,2,3)
l1: List[Int] = List(1, 2, 3)
scala> createConsecutiveNumPair1(l1)
res77: List[(Int, Int)] = List((1,2), (2,3))
scala> createConsecutiveNumPair2(l1)
res78: List[(Int, Int)] = List((2,3), (1,2))
问题:哪个运营商的CPU资源消耗最低?如果你能提出一个更好的scala方法来重写上面的方法,也会很感激。
答案 0 :(得分:3)
第一个代码的问题在于它附加O(n)
List
。所以算法基本上是O(n^2)
。
前置List
非常有效,因为它以恒定时间O(1)
运行,您可以在第二个算法中执行此操作。您可以使用它并在最后执行reverse
以使两个方法的结果相等,这大致使其在O(n)
中运行。
然而,库中已经有一个很好的方法可以满足您的需求。 sliding
正是您要找的。滑动参数定义了元组的大小。
这会给你一个List[List[Int]]
:
List(1,2,3,4).sliding(2).toList //List(List(1,2), List(2,3), List(3,4))
如果您坚持使用元组,则可以另外使用collect
或map
。请注意,当列表只有一个元素时,map
将抛出异常。
List(1,2,3,4).sliding(2).collect{
case List(a,b) => (a,b)
}.toList //List((1,2), (2,3), (3,4))
答案 1 :(得分:1)
这些方法通常只是相互调用(虽然检查实现是否确定)。 List
是一个单链接列表,针对访问头部而不是尾部进行了优化,因此向前端而不是末尾添加元素要高效得多。如果您想在列表末尾访问/添加元素,最好使用Vector
代替。
(与往常一样,如果您一直在问这个问题,那么您应该使用自动化工具来告诉您答案。如果您不使用分析器来告诉您应用的哪些部分它很慢,不值得花时间在这种微观优化上 - 你几乎肯定会优化错误的部分。)