【发布时间】: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