2017-02-20 7 views
1

Какой будет синтаксис создания 3D-матрицы в Котлине. Это Java эквивалент следующим образом:Многомерная матрица «3D» в Котлине

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

Благодаря

Edit: Кроме того, как я могу напечатать код Котлин с помощью простого 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: копировать Java кода в файл Kotlin, откроется запрос подтверждения.
  • через: используя http://try.kotlinlang.org.
+0

Спасибо , можете ли вы также рассказать мне, как мы можем напечатать его, используя простой цикл? – Han

+0

В зависимости от того, как вы хотите распечатать его, использование '.forEach' было бы одним из способов. Вы, кажется, новичок в Kotlin, поэтому вы можете посоветоваться с [ссылкой] (https://kotlinlang.org/docs/reference/basic-syntax.html), чтобы учиться в своем собственном темпе. –

+0

Хорошо, конечно. Спасибо за вашу помощь :) – Han

2

При работе с массивами на большинстве языков мне приятно создавать вспомогательный класс, а не работать непосредственно с типом 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 
    } 
} 
Смежные вопросы