如何在 Kotlin 中不出界?

How not get out of bound in Kotlin?

提问人:Bob Redity 提问时间:7/15/2022 更新时间:7/15/2022 访问量:322

问:

我得到了将当前元素与数组中的下一个元素进行比较的代码。但是它会因越界而崩溃,因为我想当它在最后一个元素上时,没有下一个元素可以比较,所以它崩溃了。如何处理这个问题以避免崩溃并停止比较最后一个元素?这是我的代码

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
    }
算法 Kotlin

评论

0赞 tobias_k 7/15/2022
首先检查是否小于数组的长度减去 1?另外,尝试将这两个项目相乘......item
0赞 Bob Redity 7/15/2022
@tobias_k你能举例说明吗?
0赞 Louis Wasserman 7/15/2022
你期望在最后一个索引出现时做什么?arr[item + 1]itemarr

答:

8赞 Klitos Kyriacou 7/15/2022 #1

直接回答您的问题:

而不是

for (item in arr.indices)

你应该写

for (item in 0..(arr.lastIndex - 1))

解释:返回范围,但在循环中,您正在检查当前索引之后的元素;因此,您应该只上到 .arr.indices0..arr.lastIndexarr.lastIndex - 1

一些进一步的建议:

  • IntArrayArray<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) }

引用:单表达式函数zipWithNextcount解构

评论

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我选择不使用,因为在这种情况下,它没有想要进入最后一个元素的直接外观,而是一个元素,而明确且更明显。还有其他合法用途(例如)。untillastIndex - 1untiluntil arr.size
0赞 gidds 7/18/2022
很公平。最后一个元素的省略确实值得向读者说明,也许版本确实做到了这一点。(如果这是答案的主要部分,那么对于那些不知道它的人来说,它可能仍然值得一提——但事实并非如此,而且答案已经足够满了!..until