首页 > 解决方案 > Kotlin 中 DynamicArray 的自定义 print() 打印出意外结果

问题描述

我有一个简单的场景,我有 Kotlin 类 DynamicArray.kt:

class DynamicArray(size: Int) {

    private var numArray: IntArray
    private var count: Int = 0

    init {
        if (size <= 0)
            throw IllegalArgumentException("Invalid value for array size")    
        numArray = IntArray(size)
    }

    fun insert(item: Int) {
        if (numArray.size == count){

            // Create newArray with double size
            val newArray = IntArray(count * 2)

            // copy old to new
            for ((index, i) in numArray.withIndex()){
                newArray[index] = i
            }

            // assign newArray to old
            numArray = newArray

        }
        numArray[count++] = item
    }

    fun print(): String {
        val arrayAsString = StringBuilder()
        arrayAsString.append("[")
        for ((index, i) in numArray.withIndex()){
            arrayAsString.append(i)
            if (index != (count - 1)){
                arrayAsString.append(", ")
            }
        }
        arrayAsString.append("]")
        return arrayAsString.toString()
    }
}

还有一个简单的 Main.kt 类,它只有:

fun main(args: Array<String>) {
    val array = DynamicArray(3)

    array.insert(1)
    array.insert(2)
    array.insert(3)

    println(array.print())

}

上面的代码在sizeDynamicArray 时完美运行并且items它打印的 eqaul

[1, 2, 3]

但是当我们插入更多项目时,初始大小例如:

fun main(args: Array<String>) {
    val array = DynamicArray(3)

    array.insert(1)
    array.insert(2)
    array.insert(3)
    array.insert(4)

    println(array.print())

}

它打印出奇怪的值,例如:

[1, 2, 3, 40, 0, ]

更新

如果我将打印方法更改为:

fun print(): String {
        return numArray.contentToString() // using built-in method
}

它仍然打印:

[1, 2, 3, 4, 0, 0]

无法弄清楚是什么导致了这个问题。

标签: kotlindata-structuresdynamic-arrays

解决方案


首先,让我们看看如何找出问题所在。

有许多调试技术,但目前最有用的通常是简单地打印内容。为了缩小问题所在,能够在每个点看到程序的状态(在本例中为 DynamicArray 的内容)真的非常有用。

您希望能够做的是添加一行,例如:

println("Point A: $array")

…在每次调用insert(). 麻烦的是,这只是打印出类似的东西:

Point A: DynamicArray@63947c6b

…这是因为 DynamicArray 没有覆盖toString(). 您可以改为调用您的print()方法 - 但您不知道错误是否存在。

如果 DynamicArray 是 a data class,您将toString()自动获得闪亮的实现。但是这个类并不适合作为数据类(并且需要许多其他更改)。但是没有什么能阻止你自己写,例如:

override fun toString() = "DynamicArray(count=$count, numArray=[${numArray.joinToString()}])"

有了它,您可以添加大量调试输出。例如:

Start: DynamicArray(count=0, numArray=[0, 0, 0])
Inserted 1: DynamicArray(count=1, numArray=[1, 0, 0])
Inserted 2: DynamicArray(count=2, numArray=[1, 2, 0])
Inserted 3: DynamicArray(count=3, numArray=[1, 2, 3])
Inserted 4: DynamicArray(count=4, numArray=[1, 2, 3, 4, 0, 0])
Inserted 5: DynamicArray(count=5, numArray=[1, 2, 3, 4, 5, 0])
[1, 2, 3, 4, 50, ]

从此,问题出在哪里就更清楚了!您可以看到两者countnumArray正确设置。所以问题一定出在你的print()方法上。

我不会在这里给出最终的解决方案,因为我认为它会帮助你更多地解决剩下的问题;我希望这已经给了你足够的开始去做这件事。(如果您需要提示,请考虑它打印了多少个数字,以及逗号放在哪里。)


推荐阅读