【问题标题】:Kotlin. The most efficient solution for finding the minimum value科特林。寻找最小值的最有效解决方案
【发布时间】:2021-11-18 14:05:27
【问题描述】:

我有一份糖的清单。 Sugar 类有两个字段:价格和重量:

data class Sugar(var price: Double, var weight: Double)

我需要通过这个字段找到最大/最小值。 我找到了两种方法来做到这一点。第一种方法是使用现成的解决方案:

        val minPrice = list.minBy { it.price }?.price
        val maxPrice = list.maxBy { it.price }?.price

        val minWeight = list.minBy { it.weight }?.weight
        val maxWeight = list.maxBy { it.weight }?.weight

第二种方式:

        var minPrice = list.first().price
        var maxPrice = list.first().price

        var minWeight = list.first().weight
        var maxWeight = list.first().weight

        for (i in 1..list.size) {
            if (list[i].price < minPrice) {
                minPrice = list[i].price
            }
            if (list[i].price > maxPrice) {
                maxPrice = list[i].price
            }
            if (list[i].weight < minWeight) {
                minWeight = list[i].weight
            }
            if (list[i].weight > maxWeight) {
                maxWeight = list[i].weight
            }
        }

两种解决方案都有效,但我需要找到最有效的一种。请告诉我哪种方法更好用,或者为此目的有更有效的解决方案。

【问题讨论】:

  • 你认为最有效的是什么?考虑第一次与第二次相比需要多少次循环迭代。您还可以随时进行一些分析,以了解哪些在实践中表现更好。无论如何,除非您遇到一些性能问题,否则这种类型的优化可能是多余的。
  • 还有maxOf,它将您的第一个示例归结为val maxWeight = list.maxOf { it.weight } 之类的行。但是,它不一定会有更好的性能。
  • 我认为 Kotlin 方法没有针对效率进行优化,二进制排序被认为是一种最佳排序算法。搜索它并尝试实现它,或使用具有它的库。
  • @Joffrey 因为二进制搜索需要知道值,所以你不能使用它。使用二进制排序,你得到第一个或最后一个,然后是最小值或最大值。复杂性是Log(N),但是通过迭代找到最小值是使用我读过的方法,并且回忆做迭代总是N。线性不仅仅是对数,因为 OP 强调的是“有效解决方案”。这就是为什么。
  • @cutiko 在 sorted 列表上,二分查找的复杂度是 O(log(n))。但是这里我们有一个(可能)未排序的列表。 (当然不能同时按价格权重排序!) 所以要进行每个二分搜索,首先你需要对列表进行排序,它的复杂度至少为 O(n ·log(n)) — 比简单扫描的 O(n) 差很多。

标签: algorithm kotlin kotlin-android-extensions


【解决方案1】:

显然,第一个解决方案在列表上迭代了四次,而第二个解决方案只迭代了一次。所以第二个选项是高性能的。你可以用函数式的方式重写解决方案

data class Metrics(val minPrice: Double = 0.0, val maxPrice: Double = 0.0, val minWeight: Double = 0.0, val maxWeight: Double = 0.0)

val (minPrice, maxPrice, minWeight, maxWeight) = list.fold(Metrics()){ acc, sugar ->
    Metrics(
      minPrice = min(sugar.price, acc.minPrice),
      maxPrice = max(sugar.price, acc.maxPrice),
      minWeight = min(sugar.weight, acc.minWeight),
      maxWeight = max(sugar.weight, acc.maxWeight)
    )
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 2020-06-07
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多