有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java整数n作为List<String>的第二个参数传递。子列表(fromIndex,toIndex),但是stacktrace说toIndex在Kotlin中是n+2

我正在解决Codewars中的一个问题:https://www.codewars.com/kata/56a5d994ac971f1ac500003e/train/kotlin 输入是一个字符串数组和一个整数k,输出是最长的字符串,可以通过从数组中连续提取k个元素并将它们连接到字符串来形成。 下面是我针对这个问题的代码,我现在正在测试它

fun main() {

    val array = arrayOf("1", "2", "3", "4", "5", "6", "7")
    println(longestConsec(array, 2))

//    Combinations below don't work either
//    val array = arrayOf("1", "2", "3", "4","5",  "6", "7", "8", "9")
//    println(longestConsec(array, 3))
//
//    val array = arrayOf("1", "2", "3", "4","5",  "6", "7", "8", "9", "10", "11")
//    println(longestConsec(array, 4))

//    val array = arrayOf("1", "2", "3", "4","5",  "6", "7", "8", "9", "10", "11", "12", "13")
//    println(longestConsec(array, 5))

}

fun longestConsec(strings: Array<String>, size: Int) =
    when {
        strings.isEmpty() || size > strings.size || size <= 0 -> ""
        else -> ConsecutiveString(strings.toList(), size)
            .searchLongestConsecutiveString(0, mutableListOf())
            .maxBy { it.length } ?: throw IllegalArgumentException()
    }

class ConsecutiveString(private val originalList: List<String>, private val size: Int) {

    tailrec fun searchLongestConsecutiveString(index: Int, acc: MutableList<String>): List<String> {
        println("start")
        return when {
            index + size >= originalList.size -> acc
            else -> {
                println(index + size)
                // *** doesn't work ***
                searchLongestConsecutiveString(
                    index + 1
                    , acc.apply { add(originalList.subList(index, index + size).joinToString("")) }
                )
                // *** doesn't work ***

                // *** works ***
//                val consecutiveString = originalList.subList(index, index + size).joinToString("")
//                searchLongestConsecutiveString(
//                    index + 1
//                    , acc.apply { add(consecutiveString) }
//                )
                // *** works ***
            }
        }
    }
}

这段代码抛出java。lang.IndexOutOfBoundsException,这是stacktrace

start

2

start

3

start

4

start

5

start

6

Exception in thread "main" java.lang.IndexOutOfBoundsException: toIndex = 8

at java.util.ArrayList.subListRangeCheck(ArrayList.java:1010)

at java.util.ArrayList.subList(ArrayList.java:1002)

at ConsecutiveString.searchLongestConsecutiveString(CodeWars.kt:37)

at CodeWarsKt.longestConsec(CodeWars.kt:22)

at CodeWarsKt.main(CodeWars.kt:4)

at CodeWarsKt.main(CodeWars.kt)

Process finished with exit code 1

这里有三件有趣的事情

  1. index+size作为sublist的第二个参数(fromIndex,toIndex)传递,在抛出异常的行之前似乎是6。然而,stacktrace显示toIndex是8,而不是6
  2. 如果字符串数组的大小小于N*2+3,则此代码不会引发IndexOutOfBoundsException,其中N是LongestConce(字符串,大小)的第二个参数
  3. 如果预先准备好字符串val并将其添加到acc(请参阅上面代码中的注释),而不是使用apply()并递归地将结果传递给方法,则不会引发异常

我在没有tailrec的情况下尝试了,但结果是一样的

有人能帮我弄清楚这是怎么回事吗

我的环境如下

操作系统:Windows 10 Home

IntelliJ IDEA:2019.2(社区版)11.0.3+12-b304。10 amd64

Kotlin:1.3.41-release-150(JRE 1.8.0_151-b12)

IntelliJ Kotlin插件:1.3.50-release-IJ2019。2-1


共 (1) 个答案

  1. # 1 楼答案

    acc.apply内调用size。在这个范围内size指的是acc的大小,而不是ConsecutiveString::size
    避免使用apply或使用标签:

    this@ConsecutiveString.size