《快學Scala》習題詳解 第3章 陣列
阿新 • • 發佈:2018-12-25
1 編寫一段程式碼,將a設定為n個隨機整數的陣列,要求隨機數位於[0,n)之間
//建立陣列,[Int]顯示指定陣列的型別,new建立長為10的陣列
//如果不使用new,建立只有一個元素10,型別為Int的陣列
val arr = new Array[Int](10)
for (i <- 0 until arr.length) arr(i) = util.Random.nextInt(10)
//加強for只能用來遍歷陣列,不能用來修改元素
for (elem <- arr) println(elem)
2 編寫一個程式,將整數陣列中相鄰的元素置換;例如,Array(1,2,3,4,5)置換後變為Array(2,1,4,3,5)
val arr = Array(1, 2, 3, 4, 5)
//從索引1開始(防止陣列越界),每隔2位迭代一次,
for (i <- 1 until (arr.length, 2)) {
var tmp = arr(i - 1)
arr(i - 1) = arr(i)
arr(i) = tmp
}
for (elem <- arr) println(elem)
3 重複前一個練習,不過這一次生成的新的值交換過的陣列,用for/yeild
val arr = Array(1, 2, 3, 4 , 5)
//為索引為偶時,輸出下一個元素,為奇,輸出上一元素
val arr2 = for (i <- 0 until arr.length) yield {
if (i % 2 == 0) {
// 防止陣列越界,長度為奇數,最後一個元素仍取自身
if (i < arr.length - 1) arr(i + 1)
else if (i == arr.length - 1) arr(i)
} else if (i % 2 != 0) arr(i - 1)
}
for (elem <- arr2) println(elem)
4 給定一個整數陣列,產生一個新的陣列,包含原陣列中的所有正值,按原有順序排序
零或者負值排在正數之後,按原有順序排序
//建立變陣列
val arr = ArrayBuffer(1, 2, -3, 3, -4, 3, 0, -1, -3, 5, 5)
//先取出>0的數
val arr2 = for (elem <- arr if (elem > 0)) yield elem
//其餘數字,追加到新陣列之後
for (elem <- arr if (elem <= 0)) arr2 += elem
for(elem <- arr2) println(elem)
5 如何計算Array[Double]的平均值
val arr = new Array[Double](10)
for (i <- 0 to 9) arr(i) = util.Random.nextDouble()
println("average:" + arr.sum / arr.length)
6 將Array[Int]中的元素進行反序排列?ArrayBuffer[Int]同樣反序
val arr = Array[Int](13, 5, 0, 1)
val arr2 = ArrayBuffer[Int](13, 5, 0, 1)
//獲取相反陣列
val arr3 = arr.reverse
val arr4 = arr2.reverse
//將相反陣列依次賦值給原陣列
for (i <- 0 until arr.length) arr(i) = arr3(i)
for (i <- 0 until arr2.length) arr2(i) = arr4(i)
7 寫一個程式,輸出陣列中的所有值,去掉重複項
val arr = ArrayBuffer[Int](13, 5, 0, 11, 25, 1, 0, 0, 2, 5)
val arr2 = arr.distinct
for (elem <- arr2) println(elem)
8 重新編寫3.4節結尾的標示便。收集負值元素的下標,反序,去掉最後一個下標,然後對每一個下標呼叫a.remove(i),並比較效率
//最原始方法,找到了逐個刪除
def f1() {
val arr = ArrayBuffer[Int](0, 1, -2, -1, 11, 25, -20, 2, 5, -3)
var flag = true
var i = 0
while (i < arr.length) { //方法改進:arr長度會動態變化
if (arr(i) >= 0) i += 1
else if (arr(i) < 0 && flag) { flag = false; i += 1 }
else arr.remove(i) //刪除元素後,後面的元素向前位移,繼續判斷
}
}
//改進版,進行元素替換 ,整體刪除尾部元素
def f2() {
val arr = ArrayBuffer[Int](0, 1, -2, -1, 11, 25, -20, 2, 5, -3)
var flag = false
val index = for (i <- 0 until arr.length if !flag || arr(i) >= 0) yield {
if (arr(i) < 0) flag = true
i
}
for (i <- 0 until index.length) arr(i) = arr(index(i))
arr.trimEnd(arr.length - index.length)
}
// 題目要求的方法,倒序刪除,位移相當要少,而且不用考慮位移帶來的索引變化
def f3() {
val arr = ArrayBuffer[Int](0, 1, -2, -1, 11, 25, -20, 2, 5, -3)
var flag = false
val index = for (i <- 0 until arr.length if arr(i) < 0) yield i
val index2 = index.reverse.dropRight(1)
for (elem <- index2) arr.remove(elem)
}
//根據系統的時間差,判斷執行的效率
val v1 = System.currentTimeMillis()
for (i <- 1 to 10000) f1()
val v2 = System.currentTimeMillis()
for (i <- 1 to 10000) f2()
val v3 = System.currentTimeMillis()
for (i <- 1 to 10000) f3()
val v4 = System.currentTimeMillis()
println(v2 - v1)
println(v3 - v2)
println(v4 - v3)
輸出結果為:85,32,46
可知f1效率最低,f2整體刪除的效率要高很多,f3倒序刪除時,效率了提高了很多
9 建立一個java.util.TimeZone.getAvailableIDs返回的時區的集合,判斷條件是它們在美洲;去掉”America/”字首並排序
val arr = java.util.TimeZone.getAvailableIDs
val arr2 = arr.filter { _.startsWith("America") } map (_.drop(8))
//本身就是排好序的,為了好玩,改倒序了
arr2.sorted.reverse.map { println }
10 引入java.awt.datatransfer._並構建一個型別為SystemFlavorMap的物件
然後以DataFlavor.imageFlavor為引數呼叫getNativesForFlavor的方法,以Scala緩衝保留返回值
為什麼要用這樣一個晦澀難懂的類?因為java標準類庫中很難得到試用java.util.List的程式碼
package day
import collection.mutable.ArrayBuffer
import java.awt.datatransfer._
import collection.JavaConversions.asScalaBuffer
//匯入後,進行隱式轉換
import scala.collection.mutable.Buffer
object get {
def main(args: Array[String]): Unit = {
val f = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap]
val buffer: Buffer[String] = f.getNativesForFlavor(DataFlavor.imageFlavor)
println(buffer.getClass) //class scala.collection.convert.Wrappers$JListWrapper
}
}