在Kotlin中,检查两个数组中的值是否相差不大的最有效方法是什么?

92dk7w1h  于 2022-12-13  发布在  Kotlin
关注(0)|答案(1)|浏览(153)

我需要检查两个IntArray对象中的值是否相差不超过1。
这是工作代码,花费的时间太长:

var pixelOutsideOfTolerance = false
         val PIXEL_VALUE_TOLERANCE = 1
            for (i in 0 until pixels1.lastIndex) {
                if (pixels1[i] - pixels2[i] > PIXEL_VALUE_TOLERANCE && pixels1[i] - pixels2[i] < - PIXEL_VALUE_TOLERANCE) {
                    pixelOutsideOfTolerance = true
                }
            }
         // Do something with pixelOutsideOfTolerance

有什么更有表现力和说服力的方式来做到这一点?

8tntrjer

8tntrjer1#

在修复性能之前,必须确保正确性:

  • 您有一个off-by-one错误,因为lastIndex是实际的最后一个索引,而不是大小。使用for (i in pixels1.indices)代替显式范围以避免这类错误
  • 您的条件永远不会为真,因为您使用的是&&而不是||。使用abs(pixels1[i] - pixels2[i]) > PIXEL_VALUE_TOLERANCE而不是更复杂的条件,检查肯定和否定,它将更容易阅读,更不可能出错(您将需要import kotlin.math.abs

现在,即使你已经知道某些像素差异超出了容差,你还是在执行整个循环。为这个循环提取一个函数,并在满足“超出容差”条件时提前返回。
应用上述内容,您现在应该有:

import kotlin.math.abs

private const val PIXEL_VALUE_TOLERANCE = 1

private fun areSimilar(pixels1: IntArray, pixels2: IntArray): Boolean {
    for (i in pixels1.indices) {
        if (abs(pixels1[i] - pixels2[i]) > PIXEL_VALUE_TOLERANCE) {
            return false
        }
    }
    return true
}

// then just use
val pixelsOutsideOfTolerance = !areSimilar(pixels1, pixels2)

如果性能不是一个要求,你也可以在这里使用一个更实用的方法。

val pixelsOutsideOfTolerance = pixels1.indices.any {
    abs(pixels1[it] - pixels2[it]) > PIXEL_VALUE_TOLERANCE
}

或者:

val pixelsOutsideOfTolerance = pixels1.asSequence().zip(pixels2.asSequence())
    .any { abs(it.first - it.second) > PIXEL_VALUE_TOLERANCE }

但是,如果这真的是一个热门的路径,你试图加快,这将是适得其反,因为拳击。

相关问题