Kotlin 中如何不越界?

Bob*_*ity 2 algorithm 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
    }
Run Code Online (Sandbox Code Playgroud)

Kli*_*cou 8

直接回答你的问题:

代替

for (item in arr.indices)
Run Code Online (Sandbox Code Playgroud)

你应该写

for (item in 0..(arr.lastIndex - 1))
Run Code Online (Sandbox Code Playgroud)

说明:arr.indices返回范围0..arr.lastIndex,但在循环中您正在检查当前索引之后的元素;因此你应该只去到arr.lastIndex - 1.

一些进一步的建议:

  • IntArray比更有效Array<Int>

  • if您可以使用(或)运算符将两个语句合并为一个||

  • 如果您正在计算符号更改的次数,则需要考虑如何解释 0。在您的代码中,输入[1,-1]会给出 1 符号更改的结果,但[1,0,-1]会给出 0,这似乎是错误的。要解决这个问题,请将 0 视为正数:

if ((arr[item] >= 0 && arr[item + 1] < 0) || arr[item] < 0 && arr[item + 1] >= 0) {
    result++
}
Run Code Online (Sandbox Code Playgroud)
  • 您不需要检查数组是否为空;只需删除该行即可。如果数组为空或者只有 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
}
Run Code Online (Sandbox Code Playgroud)

甚至更简洁:

fun myFunction(arr: IntArray) =
    arr.asList().zipWithNext().count { (a, b) -> (a >= 0) != (b >= 0) }
Run Code Online (Sandbox Code Playgroud)

参考文献:单表达式函数zipWithNextcount解构