在Scala中向后迭代两个(不同长度)列表的最有效方法是什么。
所以对于两个列表
List(a,b,c) and List(1,2)
对将是
(c,2) and (b,1)
注意:我宁愿不对每个列表做反转。
答案 0 :(得分:5)
一个简单的方法是:
List('a','b','c').reverse zip List(1,2).reverse
如果您担心效率,则反转列表为O(n)
。
根据List
的{{3}},使用reverseIterator
可能会更有效率。这样你就不会像reverse
那样创建一个新的列表,而是在你继续迭代时遍历它。那就是:
val it = list1.reverseIterator zip list2.reverseIterator //returns an Iterator you can force
it.toList // List((c,2), (b,1))
答案 1 :(得分:1)
使用并行集合
def parRevZip (a: List[String], b: List[Int]) = {
val max = Math.max(a.size, b.size)
val n = Math.abs(a.size - b.size)
if (a.size > b.size)
(max to n+1 by -1).par.map { i => (a(i-1), b(i-n-1)) }
else
(max to n+1 by -1).par.map { i => (a(i-n-1), b(i-1)) }
}
考虑到可能不同大小的列表的不同索引值,此方法从每个列表的末尾开始提取和配对相同数量的元素。
绩效需要仔细评估;对于小列表,简单的反向和压缩可以证明更简单和有效;对于大型列表,相反,这种并行方法可能会引起关注。
代码优化
def parRevZip[A,B] (a: List[A], b: List[B]) = {
val aSize = a.size
val bSize = b.size
val max = Math.max(aSize, bSize)
val n = Math.abs(aSize - bSize)
if (aSize > bSize)
(max-1 to n by -1).par.map { i => (a(i), b(i-n)) }
else
(max-1 to n by -1).par.map { i => (a(i-n), b(i)) }
}
使用非递归集合
方便的不可变集合,其中大小的计算为O(1)
(或准常量)(参见Recursive collections in Scala such as List)包括例如Array。
因此,
def parRevZip[A,B] (a: Array[A], b: Array[B])
不再遵循处理清单的要求。
答案 2 :(得分:0)
我认为你的意思是:
val a = List(1, 2, 3)
val b = List(8, 9)
val result = a.reverse zip b.reverse
答案 3 :(得分:0)
这是我对这个问题的尝试。原始列表a
和b
不重复。由于O(N)
:
List.size
object test extends App {
val a = List("a", "b", "c") //> a : List[String] = List(a, b, c)
val b = List(1, 2) //> b : List[Int] = List(1, 2)
val aSize = a.size //> aSize : Int = 3
val bSize = b.size //> bSize : Int = 2
// find which is smaller and which is bigger list
val (smaller, bigger) = if (aSize < bSize) (a, b) else (b, a)
//> smaller : List[Any] = List(1, 2)
//| bigger : List[Any] = List(a, b, c)
// skip the extra entries from head of bigger list
val truncated = bigger.drop(Math.abs(aSize - bSize))
//> truncated : List[Any] = List(b, c)
val result = if (a == smaller)
smaller.zip(truncated).reverse
else
truncated.zip(smaller).reverse //> result : List[(Any, Any)] = List((c,2), (b,1))
}