这是重写的问题。以前的不清楚。
1)简介
我需要一些很酷的结构,存储我的价值观。我需要我的酷结构添加项目,有时我需要我的酷结构折叠包含基于传递 foldFunction 。除了第2点,通常像scala.collection.immutable.List
这样的东西很棒。
请参阅此操作:
val coolContainer = 1 :: 2 :: 3 :: 4 :: Nil
val folded = coolContainer.foldLeft("")((acc, curr)=> acc + curr)
是啊!我得到了我想要的东西 - 闪亮的"1234"
字符串:)
2)其他要求 然后我希望我的酷结构可以附加到另一个。更重要的是,这样的操作必须是高效的,因为我的程序将主要进行此类操作。因此,"附加两个容器"非常期望复杂度 O(1)的算法。
所以,让我们尝试使用++
函数的标准方法将两个列表相互追加。
val locomotive = (1 to 1000000).toList
val vehicle = (1000000 to 2000000).toList
val train = locomotive ++ vehicle
那么这里发生了什么?正如大多数人可能知道的那样,Scala标准库API中的List
实现为 head ,前缀为 tail ,其中tail是另一个List。最后,列表中的最后一个元素被添加到空列表Nil
之前。
这种架构意味着如果你使用++
函数加入两个列表,引擎盖下的算法将遍历locomotive
遍历所有元素,直到最后一项,然后替换尾部(这是Nil
)具有另一个List的值 - 在我们的示例中使用vehicle
。 复杂度为O(size_of_loclomotive)。呃,:/我希望它是O(1)。
最后的问题。
是否存在scala容器,其行为与List
类似,是否符合上述要求?
弃儿,旧问题。以防万一你只是感兴趣它是如何被重新安排的,并且没有。
基本上我想选择最好的一对:将一个序列附加到另一个序列的结构和方法。在这种情况下,效率是密钥。
阅读以下内容,了解我想要实现的目标,但效率更高:
val seq1 = List(1,2,3)
val seq2 = List(4,5,6)
val seq3 = seq1 ++ seq2 //I am afraid that seq1 and seq2 will be traversed
//what is not the most efficient way to join two seqs
答案 0 :(得分:1)
如果您要反复追加,最后前缀列表将比附加的大得多,那么对于不可变数据结构的最佳选择是Vector
。但是,如果这些名单都非常短暂,那么很难打败List
;是的,你必须分配三个额外的对象,但Vector
的开销要多得多。
请记住,尽管您可以预先添加和反转(使用List
),并且有可变数据结构支持有效追加(例如ArrayBuffer
,或者{{1}如果你想在完成追加时转换成一个列表。
答案 1 :(得分:0)
追加为O(n),对于恒定时间附加,您可以使用ListBuffer并在需要不可变列表时调用toList
。