2015-09-20 70 views
0

在Scala中合併兩個相鄰索引的最有效方法是什麼?我想到的是一個令人討厭的循環與複製。在Scala中合併兩個相鄰索引的有效方法

例如,有一個緩衝器陣列A,具有長度爲N的新陣列需要被生成,使得對於A(i) = A(i) + A(i+1),其中i < N

例如,合併和求和所述第二和第三元件,並生成一個新陣列。 ArrayBuffer(1,2,4,3) => ArrayBuffer(1,6,3)

更新: 我想我想出了一些解決方案,但不喜歡它太多。任何改善建議將不勝感激。

scala> val i = 1 i: Int = 1

scala> ArrayBuffer(1,2,4,3).zipWithIndex.foldLeft(ArrayBuffer[Int]())((k,v)=> if(v._2==i+1){ k(k.length-1) =(k.last+v._1);k; }else k+= v._1)

+0

爲什麼'(1,6,3)'和'不是(3,6,7)'? – zero323

+0

它應該只合並和相鄰的索引,它是第一個也是最後一個元素的情況並不有趣。我在中間合併指數的挑戰。 –

回答

3

得到鄰居的最簡單的方法是使用sliding方法。

a.sliding(2, 1).map(_.sum) 

其中第一個參數是大小,第二個參數是步長。

如果你想保持第一和最後一個元素完整這樣的事情應該工作:

a.head +: a.drop(1).dropRight(1).sliding(2, 1).map(_.sum).toArray :+ a.last 

如果你想避免附加/添加你可以重寫它複製和排列如下:

val aa = a.sliding(2, 1).map(_.sum).toArray 
aa(0) = a.head 
aa(aa.size - 1) = a 

或使用ListBuffer它提供了恆定的時間前置和追加。

應該也可以使用Iterators

val middle: Iterator[Int] = a.drop(1).dropRight(1).sliding(2, 1).map(_.sum) 
(Iterator(a.head) ++ middle ++ Iterator(a.last)).toArray // or toBuffer 
+0

感謝您的建議!解決方案的運行時間是什麼?它是O(N)嗎?我用foldLeft建議更新了描述,但是我不太喜歡它。 –

+0

它是O(N),雖然'+:'和':+'返回的數組不是最優的。如果你喜歡避免這種情況,你可以像這樣拆分它:'val aa = a.sliding(2,1).map(_。sum).toArray; aa(0)= a.head; aa(aa.size - 1)= a.last'或者使用'ListBuffer',它在同一時間提供'append'和prepend。 – zero323

相關問題