2017-02-20 160 views
1

在Kotlin中創建3D矩陣的語法是什麼?它相當於Java如下:Kotlin中的多維「3D」矩陣

public static final int[][][] data = {{{0,0},{0}},{{0,1},{0}},{{1,0},{0}},{{1,1},{1}}}; 

感謝

編輯: 還有我怎麼能打印使用簡單的println科特林代碼?

回答

1

Kotlin目前不支持數組文字。

您可以使用arrayOf()intArrayOf()組合:

val data = arrayOf(
    arrayOf(intArrayOf(0, 0), intArrayOf(0)), 
    arrayOf(intArrayOf(0, 1), intArrayOf(0)), 
    arrayOf(intArrayOf(1, 0), intArrayOf(0)), 
    arrayOf(intArrayOf(1, 1), intArrayOf(1)) 
) 

如果需要,可以減少使用進口走樣冗長一點:

import kotlin.arrayOf as arr 
import kotlin.intArrayOf as iarr 

val data = arr(
    arr(iarr(0, 0), iarr(0)), 
    arr(iarr(0, 1), iarr(0)), 
    arr(iarr(1, 0), iarr(0)), 
    arr(iarr(1, 1), iarr(1)) 
) 

還要注意的是,你可以自動將Java代碼轉換爲Kotlin

  • in IntelliJ IDEA:copy Java編碼到Kotlin文件中,確認提示將打開。
  • 在線:使用http://try.kotlinlang.org
+0

謝謝,你還可以告訴我如何使用簡單的for循環打印它? – Han

+0

取決於你想如何打印它,使用'.forEach'將是一種方法。您似乎對Kotlin是新手,因此您可能需要諮詢[參考資料](https://kotlinlang.org/docs/reference/basic-syntax.html)以按自己的步調進行學習。 –

+0

好的。感謝您的幫助:) – Han

2

在大多數語言中使用數組時,我發現創建輔助類非常好,而不是直接使用int[][][]類型。這樣可以確保某些不變量保持不變(如具有相同長度的所有行),並確保更好的數據局部性。它還可以讓你高效地執行某些操作,如切片,子矩陣,轉置等。

我通常的一組類似乎是3D的。 (儘管我可能會對保存的類型進行模板設置,而不是對其進行硬編碼,但對於Int) 它很不完整,但最後的主要部分顯示了有多少個函數可以工作。

不過來向您展示如何創建值的三維陣列,你可以做

val V = /* .. as in mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu's answer */ 
val M = Matrix3D(NX,NY,NZ).transform({ v, ix, iy, iz -> V[ix][iy][iz] }) 

進一步的例子是

fun main(args: Array<String>) { 

    // Create an empty matrix 
    val v = Matrix3D(4,4,2); 

    // We can access elements via [a,b,c] or [a][b][c] 
    v[0,1,1] = 7; 
    print(v) 
    println("v[0,1,1]=" + v[0,1,1]) 
    println("v[0][1][1]=" + v[0][1][1]) 

    println("-----") 
    // Make the matrix a little more interesting 
    v.transform({ w,ix,iy,iz -> ix+iy+iz}) 
    print(v) 

    println("-----") 
    // Transform just the slice with ix=2 
    // Slices are fast, as they copy no elements. 
    // but if you change them you change the original 

    v[2].transform({w,iy,iz -> w+3}) 
    print(v) 

    // If you dont want to change the original you can always 
    // create an independent copy 
    print(v[2].bake().transform({w,iy,iz -> w-3})) 

    println("-----") 
    // W is the slice of v with ix=0 
    // Can easily extend the slicing options to allow slicing along 
    // any axis - I'd like to add v[_,1,_] to mean the slice with iy=1 
    // but I've not got to that yet. 
    val W = v[0] 
    print("W=\n") 
    print(v[0]) 
    print("W^T=\n") 

    // Fast transpose, no elements are copied. 
    val WT=v[0].transpose() 
    print(WT) 

    // Changing the transpose slice writes back into the original 
    WT[1,1]=5 
    print(V) 
} 

fun print(M:Matrix3D) { 
    for(iz in 0..(M.nz-1)) { 
     for(iy in 0..(M.ny-1)) { 
      for(ix in 0..(M.nx-1)){ 
       print("%d ".format(M[ix,iy,iz])) 
      } 
      print("\n") 
     } 
     print("\n") 
    } 
} 

fun print(M:Matrix2D) { 
    for(iy in 0..(M.ny-1)) { 
     for(ix in 0..(M.nx-1)){ 
      print("%d ".format(M[ix,iy])) 
     } 
     print("\n") 
    } 
} 

庫的代碼如下所示:

class Matrix1D(
    val v:Array<Int>, 
    val nx:Int, 
    val offset:Int, 
    val xstride:Int) { 
     // TODO: Check that the nx,offset,strides etc are valid 

    constructor(nx:Int) : this(Array(nx,{i->0}), nx, 0, 1) { 

    } 

    fun offsetof(ix:Int):Int { 
     return offset + ix*xstride 
    } 

    operator fun get(ix:Int): Int { 
     return v[offsetof(ix)] 
    } 

    operator fun set(ix:Int, v:Int) { 
     this.v[offsetof(ix)] = v 
    } 

    fun reverse() : Matrix1D { 
     return Matrix1D(v, nx, offsetof(nx-1), -xstride) 
    } 

    fun submatrix(startx:Int, newNX:Int) : Matrix1D { 
     return Matrix1D(v,newNX,offsetof(startx), xstride) 
    } 

    fun transform(body: (Int, Int) -> Int) { 
     for(ix in 0..(nx-1)){ 
      this[ix] = body(this[ix], ix) 
     } 
    } 

    fun bake() : Matrix1D { 
     val rv = Matrix1D(nx); 
     for(ix in 0..(nx-1)) { 
      rv[ix] = this[ix] 
     } 
     return rv 
    } 
} 

class Matrix2D(
    val v:Array<Int>, 
    val nx:Int, val ny:Int, 
    val offset:Int, 
    val xstride:Int, val ystride:Int) { 
     // TODO: Check that the nx,ny,offset,strides etc are valid 

    constructor(nx:Int, ny:Int) : this(Array(nx*ny,{i->0}), nx, ny, 0, 1, nx) { 

    } 

    fun offsetof(ix:Int,iy:Int): Int { 
     return offset + ix*xstride + iy*ystride 
    } 

    operator fun get(ix:Int,iy:Int): Int { 
     return v[offsetof(ix,iy)] 
    } 

    operator fun set(ix:Int,iy:Int,v:Int) { 
     this.v[offsetof(ix,iy)] = v 
    } 

    operator fun get(ix:Int): Matrix1D { 
     return Matrix1D(v, ny, offsetof(ix,0), ystride) 
    } 

    fun transpose(): Matrix2D { 
     return Matrix2D(v,ny,nx,offset,ystride,xstride) 
    } 

    fun submatrix(startx:Int, starty:Int, newNX:Int, newNY:Int) : Matrix2D { 
     return Matrix2D(v,newNX,newNY,offsetof(startx,starty), xstride, ystride) 
    } 

    fun transform(body: (Int, Int, Int) -> Int) { 
     for(iy in 0..(ny-1)) { 
      for(ix in 0..(nx-1)){ 
       this[ix,iy] = body(this[ix,iy], ix,iy) 
      } 
     } 
    } 

    fun bake() : Matrix2D { 
     val rv = Matrix2D(nx,ny); 
     for(ix in 0..(nx-1)) { 
      for(iy in 0..(ny-1)) { 
        rv[ix,iy] = this[ix,iy] 
      } 
     } 
     return rv 
    } 
} 

class Matrix3D(
    val v:Array<Int>, 
    val nx:Int, val ny:Int, val nz:Int, 
    val offset:Int, 
    val xstride:Int, val ystride:Int, val zstride:Int) { 
     // TODO: Check that the nx,ny,nz,offset,strides etc are valid 

    constructor(nx:Int, ny:Int, nz:Int) : this(Array(nx*ny*nz,{i->0}), nx, ny, nz, 0, 1, nx, nx*ny) { 

    } 
    operator fun get(ix:Int,iy:Int,iz:Int): Int { 
     return v[offset + ix*xstride + iy*ystride + iz*zstride] 
    } 

    operator fun set(ix:Int,iy:Int,iz:Int, v:Int) { 
     this.v[offset + ix*xstride + iy*ystride + iz*zstride] = v 
    } 

    operator fun get(ix:Int): Matrix2D { 
     return Matrix2D(v, ny, nz, offset + ix*xstride, ystride, zstride) 
    } 

    fun transform(body: (Int, Int, Int, Int) -> Int) { 
     for(iz in 0..(nz-1)) { 
     for(iy in 0..(ny-1)) { 
      for(ix in 0..(nx-1)){ 
       this[ix,iy,iz] = body(this[ix,iy,iz], ix,iy,iz) 
      } 
     } 
    } 
} 

    fun bake() : Matrix3D { 
     val rv = Matrix3D(nx,ny,nz); 
     for(ix in 0..(nx-1)) { 
      for(iy in 0..(ny-1)) { 
       for(iz in 0..(nz-1)){ 
        rv[ix,iy,iz] = this[ix,iy,iz] 
       } 
      } 
     } 
     return rv 
    } 
}