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
这里有三件有趣的事情
- index+size作为sublist的第二个参数(fromIndex,toIndex)传递,在抛出异常的行之前似乎是6。然而,stacktrace显示toIndex是8,而不是6李>
- 如果字符串数组的大小小于N*2+3,则此代码不会引发IndexOutOfBoundsException,其中N是LongestConce(字符串,大小)的第二个参数
- 如果预先准备好字符串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 楼答案
在
acc.apply
内调用size
。在这个范围内size
指的是acc
的大小,而不是ConsecutiveString::size
避免使用
apply
或使用标签: