提问人:Bob Redity 提问时间:7/15/2022 更新时间:7/15/2022 访问量:322
如何在 Kotlin 中不出界?
How not get out of bound in Kotlin?
问:
我得到了将当前元素与数组中的下一个元素进行比较的代码。但是它会因越界而崩溃,因为我想当它在最后一个元素上时,没有下一个元素可以比较,所以它崩溃了。如何处理这个问题以避免崩溃并停止比较最后一个元素?这是我的代码
fun myFunction(arr: Array<Int>): Int{
if (arr.isEmpty()) return 0
var result = 0
for (item in arr.indices) {
if (arr[item] > 0 && arr[item + 1] < 0){
result ++
}
if (arr[item] < 0 && arr[item + 1] > 0){
result ++
}
}
return result
}
答:
8赞
Klitos Kyriacou
7/15/2022
#1
直接回答您的问题:
而不是
for (item in arr.indices)
你应该写
for (item in 0..(arr.lastIndex - 1))
解释:返回范围,但在循环中,您正在检查当前索引之后的元素;因此,您应该只上到 .arr.indices
0..arr.lastIndex
arr.lastIndex - 1
一些进一步的建议:
IntArray
比Array<Int>
您可以使用 (or) 运算符将这两个语句合并为一个语句。
if
||
如果要计算符号变化的次数,则需要考虑如何解释 0。在您的代码中,输入 将给出 1 符号变化的结果,但会给出 0,这似乎是错误的。要解决此问题,请将 0 视为正数:
[1,-1]
[1,0,-1]
if ((arr[item] >= 0 && arr[item + 1] < 0) || arr[item] < 0 && arr[item + 1] >= 0) {
result++
}
您无需检查数组是否为空;只需删除该行即可。如果数组为空或只有 1 个元素,则不会进入循环。
最后,您可以使用标准库的一些很酷的功能(在文档中查找它们以学习它们),这可以使您的函数简洁:
fun myFunction(arr: IntArray): Int {
var result = 0
arr.asList().zipWithNext().forEach { (a, b) ->
if ((a >= 0 && b < 0) || (a < 0 && b >= 0))
result++
}
return result
}
甚至更简洁:
fun myFunction(arr: IntArray) =
arr.asList().zipWithNext().count { (a, b) -> (a >= 0) != (b >= 0) }
引用:单表达式函数、zipWithNext、count、解构。
评论
0赞
gidds
7/16/2022
for (item in 0 until arr.lastIndex)
意思与 相同,可以说更容易阅读。(until
与 LIKE 类似,只是它排除了 end 元素。但是,是的,正如您所展示的,有更简单的方法。for (item in 0..(arr.lastIndex - 1))
..
1赞
Klitos Kyriacou
7/18/2022
@gidds我选择不使用,因为在这种情况下,它没有想要进入最后一个元素的直接外观,而是一个元素,而明确且更明显。还有其他合法用途(例如)。until
lastIndex - 1
until
until arr.size
0赞
gidds
7/18/2022
很公平。最后一个元素的省略确实值得向读者说明,也许版本确实做到了这一点。(如果这是答案的主要部分,那么对于那些不知道它的人来说,它可能仍然值得一提——但事实并非如此,而且答案已经足够满了!..
until
评论
item
arr[item + 1]
item
arr