二进制搜索ArrayBuffer

时间:2019-03-21 15:10:03

标签: algorithm scala performance data-structures binary-search-tree

因此,我有一个ArrayBuffer [Signal],其中每个Signal都有一个时间戳(该数组按该时间戳排序)。我想进行二进制搜索并返回一定范围内的信号的Seq [Signal]。现在,它是通过线性搜索完成的,基本上是因为我来自Java,并且是Scala的新手。哪种方法最好?

代码如下:

/userinfo

3 个答案:

答案 0 :(得分:0)

您可以使用“搜索”进行二进制搜索。

import scala.collection.Searching._

val signalWithLowerBoundTimestamp = ???
val signalWithUpperBoundTimestamp = ???
val lower = signals.search(signalWithLowerBoundTimestamp)(
    Ordering.by(_.timestamp)).insertionPoint
// If the upper bound is an exact match, add one
// to make sure it's included in the slice.
val upper = signals.search(signalWithUpperBoundTimestamp)(
    Ordering.by(_.timestamp)) match {
  case Found(i) => i + 1
  case InsertionPoint(i) => i
}
val result = signals.slice(lower, upper)

答案 1 :(得分:0)

您可以使用dropWhiletakeWhile
这样,您可以保存所有可变性和迭代。

注意:,它仍然是线性的,但在 Scala 中,它更具功能且更常见。

private def getSignalsFromCache(mapId: String, mac: String, startTime: Long, endTime: Long): Seq[Signal] =
  getCache(VehicleWithMap(mapId, mac)
    .dropWhile(_.timestamp < startTime)
    .takeWhile(_.timestamp <= endTime)
}

(请务必先进行测试,您可能需要对条件有所了解)

答案 2 :(得分:0)

我不知道scala,但是这是一个二进制搜索,您可以将其与更多功能样式的答案进行比较。我认为其中没有任何可耻之处。请注意,对结束索引进行二进制搜索没有任何好处,因为无论如何您都必须复制元素:

private def getSignalsFromCache(mapId: String, mac: String, startTime: Long, endTime: Long): Seq[Signal] = {

    val signals = getCache(VehicleWithMap(mapId, mac))

    var startIndex: Int = 0
    var endIndex: Int = signals.size

    while(startIndex<endIndex) {
        var testIndex: int = startIndex + (endIndex-startIndex)/2
        if (signals(testIndex).timestamp < startTime) {
            startIndex = testIndex + 1
        } else {
            endIndex = testIndex
        }
    }

    while(endIndex < signals.size && signals(endIndex).timestamp <= endTime) {
        endIndex = endIndex + 1
    }
    signals.slice(startIndex, endIndex)
}

请注意,我在信号timestamp == endTime的末尾添加了信号,因为那是您所做的……但是这会使界面有些奇怪。通常,这样的方法将被编写为使用startTime <= timeStamp < endTime返回信号,所以也许您想考虑更改它。