Kotlin中的多维“3D”矩阵

在Kotlin中创建3D矩阵的语法是什么? 它的Java等价物如下:

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

谢谢

编辑:另外,如何使用简单的println打印Kotlin代码?

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

  • 在IntelliJ IDEA中:将Java代码复制到Kotlin文件中,将打开确认提示。
  • 在线:使用http://try.kotlinlang.org

在大多数语言中使用数组时,我发现创建一个辅助类非常好,而不是直接使用int[][][]类型。 这样可以确保某些不变量保持不变(比如所有具有相同长度的行),并确保更好的数据局部性。 它也可以让你高效地执行某些操作,如切片,子矩阵,转置等。

我通常的一组类看起来像这样的3D。 (尽管我可能会对存储的类型进行模板化,而不是对Int硬编码)。它相当不完整,但最后的主要部分显示了有多少个函数可以工作。

但是要显示如何从值中创建3D数组,您可以执行此操作

 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 } }