Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 对ArrayBuffer的二进制搜索_Algorithm_Scala_Performance_Data Structures_Binary Search Tree - Fatal编程技术网

Algorithm 对ArrayBuffer的二进制搜索

Algorithm 对ArrayBuffer的二进制搜索,algorithm,scala,performance,data-structures,binary-search-tree,Algorithm,Scala,Performance,Data Structures,Binary Search Tree,因此,我有一个ArrayBuffer[Signal],其中每个信号都有一个时间戳(数组按这个时间戳排序)。我想进行二进制搜索并返回一定范围内信号的Seq[Signal]。现在它是用线性搜索完成的,基本上是因为我来自Java,我是Scala的新手。哪种方法最好 代码如下: private def getSignalsFromCache(mapId: String, mac: String, startTime: Long, endTime: Long): Seq[Signal] = { val

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

代码如下:

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

val signals = getCache(VehicleWithMap(mapId, mac))
val result: ArrayBuffer[Signal] = new ArrayBuffer[Signal]()

if (signals.isEmpty) {
  return signals
}

var startIndex: Int = 0
if (startTime > signals.head.timestamp) {

  while (startIndex < signals.size && signals(startIndex).timestamp < startTime) {
    startIndex += 1
  }
}

var finished: Boolean = false
var currentIndex = startIndex
while (!finished && currentIndex < signals.size) {
  val timestamp = signals(currentIndex).timestamp
  if (timestamp > endTime) {
    finished = true
  }
  else {
    result += signals(currentIndex)
  }
  currentIndex += 1
}
result
}
private def getSignalsFromCache(mapId:String,mac:String,startTime:Long,endTime:Long):Seq[Signal]={
val signals=getCache(VehicleWithMap(mapId,mac))
val结果:ArrayBuffer[信号]=新的ArrayBuffer[信号]()
if(signals.isEmpty){
返回信号
}
变量startIndex:Int=0
if(startTime>signals.head.timestamp){
while(startIndex结束时间){
完成=正确
}
否则{
结果+=信号(当前索引)
}
当前索引+=1
}
后果
}

您可以使用搜索进行二进制搜索

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)
您可以使用&.
这样,就可以保存所有的易变性和迭代

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

private def getSignalsFromCache(mapId: String, mac: String, startTime: Long, endTime: Long): Seq[Signal] =
  getCache(VehicleWithMap(mapId, mac)
    .dropWhile(_.timestamp < startTime)
    .takeWhile(_.timestamp <= endTime)
}
private def getSignalsFromCache(mapId:String,mac:String,startTime:Long,endTime:Long):Seq[Signal]=
getCache(VehicleWithMap(mapId,mac)
.dropWhile(u.timestamp.takeWhile(u.timestamp我不知道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)
}
private def getSignalsFromCache(mapId:String,mac:String,startTime:Long,endTime:Long):Seq[Signal]={
val signals=getCache(VehicleWithMap(mapId,mac))
变量startIndex:Int=0
var endIndex:Int=signals.size

而(startIndex)据我所知,数组缓冲区是按升序排序的,对吗?@LuisMiguelMejíaSuárez是的,这似乎很简单。用
startIndex+=1
替换为
startIndex+=0.5长度的一半,方向正确()
。这只是记账的问题。排序。按(\u.timestamp)如果有多个具有下限时间戳的信号,此方法可能会错过其中一些信号,因为search.search不一定会返回第一个匹配结果。您可以通过对顺序进行调整来解决这一问题,但此时只编写二进制搜索就变得更简单、更清晰了。@Guillem你能告诉我发生的错误吗?也许你需要导入排序吗?@Matt是的,你可以用线性搜索来跟踪二进制搜索的边缘,但是如果有很多重复项,这会影响运行时间。我同意如果考虑重复项,实现二进制搜索会更好。@BrianMcCutchon问题是我非常擅长Scala.Signal中的er是一个case类,因此当我执行signals.search(startTime)(Ordering.by(u.timestamp))时,IDE无法解析,因为没有定义特殊的顺序。我的case类是这样的:case类Signal(ap:AccessPoint,timestamp:Long,rssi:Double,mac:String=”“).我如何定义排序以及如何使用它调用方法搜索?谢谢Brian,你太棒了!