快學Scala-第三章 數組相關操作


知識點:

1.定長數組 Array

val nums = new Array[Int](10) //10個整數的數組,所有元素初始化為0
val a = new Array[String](10) //10個元素的字符串數組,所有元素初始化為null
val s= Array("Hello","World") //長度為2的Array(String) 類型是編譯器推斷出來的,已提供初始值就不需要new
s(0) = "Goodbye" //Array("Google","World") 使用()而不是[]來訪問元素

Scala的Array以Java數組方式實現,例子中的s對應的是java.lang.String[]

2.變長數組:數組緩沖 ArrayBuffer

對於長度按需要變化的數組,Java-ArrayList || C++-vector || Scala-ArrayBuffer

  val b = ArrayBuffer[Int]() //或者 new ArrayBuffer[Int]
  b += 1 //ArrayBuffer(1) 用 += 在尾端添加元素
  b += (1,2,3,4,5) //ArrayBuffer(1,1,2,3,4,5) 在尾端添加多個元素,用括號包起來
  b ++= Array(6,7,8) //ArrayBuffer(1,1,2,3,4,5,6,7,8) 用  ++= 追加任何集合
  b.trimEnd(5) //ArrayBuffer(1,1,2,3)移除最后5個元素

在數組緩沖的尾部添加或移除元素是一個高效的操作。也可以在任意位置插入和刪除元素,這樣的操作不高效,引發位置后的元素都必須被平移。

  b.insert(2, 9) //ArrayBuffer(1,1,9,2,3)
  b.insert(2, 10,11) //ArrayBuffer(1,1,10,11,9,2,3)
  b.remove(2) //ArrayBuffer(1,1,11,9,2,3)
  b.remove(2,3) //ArrayBuffer(1,1,3)

有時候你需要構建一個Array,但不知道元素有多少個,可以先構建ArrayBuffer,再調用b.toArray();反過來,調用a.toBuffer可以將一個數組a轉換為一個數組緩沖。

3.遍歷數組和數組緩沖

for(i <- 0 until a.length) //變量i值從0取到a.length-1
    println(i + ": " + a(i))

for(i <- 區間) 會讓i遍歷區間所有值。

0 until (a.length, 2) 
  //Range(0,2,4,6,...) 每兩個元素一跳
  
  (0 until a.length).reverse
  //Range(...,3,2,1,0) 逆序
  
  for(elem <- a)  //不使用數組下標時
    println(elem)

3.數組轉換

val aa = Array(2,5,8,9)
  val result = for(elem <- aa) yield 2 * elem
  //result是Array(4,10,16,18)

for(…) yield 循環創建了一個類型與原始集合相同的新集合。結果包含yield之后的表達式,每次迭代對應一個。當你遍歷一個集合時,你只想處理那些滿足特定條件的元素,可以通過 守衛 :for 中的 if 實現。

for(elem <- aa if elem % 2 == 0) yield 2 * elem
//另一種實現方法
a.filter(_ % 2 == 0).map(2 * _)
a.filter{ _ % 2 == 0} map { 2 * _}

4.常用方法

sum\max\sorted sum方法的數組元素類型必須是數值類型,sorted方法將數組或緩沖數組排序后返回經過排序的數組或緩沖數組,不修改原始版本。

顯示數組或緩沖數組的內容,可以用mkString方法。

5.多維數組是通過數組的數組實現的

  val matrix = Array.ofDim[Double](3,4)
  matrix(row)(column) = 42
//創建不規則的數組  
  val triangle = new Array[Array[Int]](10)
  for(i <- 0 until triangle.length)
    triangle(i) = new Array[Int](i+1)


練習:(答案源鏈接

1.編寫一段代碼,將a設置為一個n個隨機整數的數組,要求隨機數介於0(包含)和n(不包含)之間

class test{
  def main(args:Array[Int]){
    getArr(10).foreach(println)
  }
  
  def getArr(n:Int): Array[Int] = {
    val a = new Array[Int](n)
    val rand = new scala.util.Random()
    for(i <- a) yield rand.nextInt()
  }
  
}

2.編寫一個循環,將整數數組中相鄰的元素置換

class test{
  def main(args:Array[Int]){
    val arr = Array(1,2,3,4,5)
    revert(arr)
    arr.foreach(println)
  }
  
  def revert(a:Array[Int]) = {
    for(i <- 0 until (a.length - 1,2)){
      val t = a(i)
      a(i) = a(i+1)
      a(i+1) = t
    }
  }
}

3.重復前一個練習,不過這次生成一個新的值交換過的數組。用for/yield。

class test{
  def main(args:Array[Int]){
    val a = Array(1,2,3,4,5)
    val b = revertYield(a)
    b.foreach(println)
  }
  
  def revertYield(a:Array[Int]) = {
    for(i <- 0 until a.length) yield { 
      if( i < (a.length - 1) && i % 2 == 0){
        //偶數下標時,則交換下一個相鄰的元素值
        val t = a(i)
        a(i) = a(i+1)
        a(i+1) = t
      }
      a(i) //因為生成新的數組,每一個元素都要返回
    }
  }
}

4.給定一個整數數組,產出一個新的數組,包含元數組中的所有正值,以原有順序排列,之后的元素是所有零或負值,以原有順序排列。

import scala.collection.mutable.ArrayBuffer

class test{
  def main(args:Array[Int]){
    val a = Array(1,-2,0,4,5,0,-3)
    val b = reCombine(a)
    b.foreach(println)
  }
  
  def reCombine(a:Array[Int]) = {
    val buf = new ArrayBuffer[Int]();
    buf ++= (for( i <- a if(i > 0)) yield i)
    buf ++= (for( i <- a if(i == 0 || i < 0)) yield i)
    buf.toArray
  }
}

5.如何計算Array[Double]的平均值?

class test{
  def main(args:Array[Int]){
    val a = Array(1.0,5.6,0.0,-3.0)
    val b = average(a)
    println(b)
  }
  
  def average(a:Array[Double]) = {
    var t = 0.0
    for(i <- a){
      t += i
    }
    t/a.length
  }
  
  def ave(a:Array[Double]) = {
     a.sum / a.length
  }
}

6.如何重新組織Array[Int]的元素將它們反序排列?對於ArrayBuffer[Int]你又會怎么做呢?

import scala.collection.mutable.ArrayBuffer

object Hello {       
  def main(args: Array[String]) {          
  val a = Array(1,2,3,4,5)
    reverseArray(a)
    println("array reverse:")
    a.foreach(println)
    val b = a.reverse //將a的值逆序回去了
     b.foreach(println)
    
    println("bufferArray reverse:")
    val c = ArrayBuffer(6,7,8,9,0);
    val d = c.reverse        
    d.foreach(println)
  }     
  def reverseArray(a:Array[Int]) = {
    for( i <- 0 until (a.length / 2)){
      val t = a(i)
      a(i) = a(a.length-1-i)
      a(a.length-1-i)=t
    }
  }
}

7.編寫一段代碼,產出數組中的所有值,去掉重復項

import scala.collection.mutable.ArrayBuffer

object Hello {       
  def main(args: Array[String]) {          
    val ab = new ArrayBuffer[Int]()
    val c = new ArrayBuffer[Int]()
    println("Input the array line,separated by a space,ended with an enter.")
    val input = readLine().toString().split(' ');
    for(i <- input){
      ab += i.toInt
    }
//    ab.foreach(println)
    c ++= ab.distinct
    c.foreach(println) 
  }     
}

8.重新編寫3.4節結尾的示例。收集負值元素的下標,反序,去掉最后一個下標,然后對每一個下標調用a.remove(i)。比較這樣做的效率和3.4節中另外兩種方法的效率

import scala.collection.mutable.ArrayBuffer

object Hello {       
  def main(args: Array[String]) {          
    val a = ArrayBuffer(1,2,4,-2,0,-1,-4,8)
    deleteNeg(a)
    a.foreach(println) 
  }  
  def deleteNeg(a:ArrayBuffer[Int]) = {
    val indexes = for(i <- 0 until a.length if a(i) < 0 ) yield  i 
    //不能val b = indexex.reverse.trimEnd(1) reverse后,它是一個Seq序列。
    //value trimEnd is not a member of scala.collection.immutable.IndexedSeq[Int]
    val b = new ArrayBuffer[Int]()
    b ++= indexes.reverse
    b.trimEnd(1)
    //remove是ArrayBuffer的函數,如果傳入的是Array,則需要調用toBuffer
    for(i <- b){
      a.remove(i)
    }
  }
}

9.創建一個由java.util.TimeZone.getAvailableIDs返回的時區集合,判斷條件是它們在美洲,去掉”America/“前綴並排序。

import scala.collection.mutable.ArrayBuffer
import scala.collection.JavaConversions.asScalaBuffer

object Hello
{
  def main(args: Array[String])  = {
    var c = timeZoneName()
    c.foreach(println)
  }        
  
  def timeZoneName() = {
    val arr = java.util.TimeZone.getAvailableIDs();
    val tmp = (for (i <- arr if i.startsWith("America/")) yield {
      i.drop("America/".length)
    })
    scala.util.Sorting.quickSort(tmp)
    tmp
  }
}

10.引入java.awt.datatransfer._並構建一個類型為SystemFlavorMap類型的對象,然后以DataFlavor.imageFlavor為參數調用getNativesForFlavor方法,以Scala緩沖保存返回值。

import scala.collection.JavaConversions.asScalaBuffer
import scala.collection.mutable.Buffer
import java.awt.datatransfer._

object Hello
{
  def main(args: Array[String])  = {
     val flavors = SystemFlavorMap.getDefaultFlavorMap().asInstanceOf[SystemFlavorMap]
     val buf : Buffer[String] = flavors.getNativesForFlavor(DataFlavor.imageFlavor);
     buf.foreach(println);
  }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM