有效地找到一个对象,落在特定数的范围内范围内、定数、落在、有效地

2023-09-11 06:14:05 作者:有什么熬不过

这是我的基本的问题:我给一个 currentTime的。例如,750个秒。我也有,其中包含1000-2000对象,每个对象都有一个的startTime endTime的,以及一个数组 _id 属性。鉴于 currentTime的,我需要找到具有的startTime endTime的落在该范围内的 - 例如,的startTime:740 结束时间:755

什么是最有效的方式来做到这一点的Javascript?

我只是一直在做这样的事情,对于初学者:

  VAR arrayLength = array.length;
变种X = 0;
而(X< arrayLength){
 如果(currentTime的> =阵列[X] .startTime和放大器;&安培; currentTime的< =阵列[X] .endTime){
  //然后我发现我的对象
 }
X ++;
};
 

但我怀疑,循环不在这里最好的选择。有什么建议?

编辑:为了清楚起见, currentTime的有下跌的的startTime 和 endTime的

我的解决办法:我的数据的结构得到了我一定的好处,可以让我把事情简单化了一点。我做了一个基本的二进制搜索,如建议,因为该数组已按startTime时。我还没有完全测试这个东西的速度,但我怀疑这是一个公平的有点快,尤其是对于较大的阵列。

  VAR的binarySearch =功能(阵列,currentTime的){

  VAR低= 0;
  VAR高= array.length  -  1;
  变种我;

  而(低< =高){
    I = Math.floor((低+高)/ 2);

    如果(数组[我] .startTime< = currentTime的){

      如果(数组[我] .endTime> = currentTime的){
        //这是一个
        返回数组[我] ._ ID;

      } 其他 {
        低= I + 1;
      }
    }

    其他 {
      高= I  -  1;
    }
  }

  返回null;
}
 
我需要PbO2含量X 列的5个数字中有一个超出范围则判定为不合格,显示在红色单元格内,只需要一个总得判定结

解决方案

要解决这个问题,最好的方法取决于多少次,你将不得不打电话给你的搜索功能。

如果您调用函数只是几次,假设 M 时间,去为线性搜索。这个函数的调用的总体复杂性将是 O(MN)

如果您调用你的函数多次,然后通过的许多的我的意思是超过的log(n)倍你应该:

排序您在阵列O(nlogn)的startTime ,然后通过 endTime的如果你有几个项目具有相等的值的startTime 请二进制搜索找到元素的范围的startTime< = X 。这就意味着,两个的二进制搜索:一个是启动,一个是结束范围的范围。这是在做 O(LOGN) 请在线性搜索[开始,结束] 。你所要做的线性搜索,因为 startTimes 的顺序告诉你任何关于 endTimes 。这可能是之间的任何 O(1) O(N),它取决于你的段的分配和对 X 的值。

平均情况: O(nlogn)的初始化和 O(LOGN)对于每个搜索

最坏的情况:包含许多相等的部分,或者说有一个共同的区间段,并寻找在此区间的数组。在这种情况下,你会做 O(nlogn)的初始化和 O(N + LOGN)= O(N)搜索。

Here's my basic problem: I'm given a currentTime. For example, 750 seconds. I also have an array which contains 1000 to 2000 objects, each of which have a startTime, endTime, and an _id attribute. Given the currentTime, I need to find the object that has a startTime and endTime that falls within that range -- for example, startTime : 740, endTime : 755.

What is the most efficient way to do this in Javascript?

I've simply been doing something like this, for starters:

var arrayLength = array.length; 
var x = 0;
while (x < arrayLength) {
 if (currentTime >= array[x].startTime && currentTime <= array[x].endTime) {
  // then I've found my object
 }
x++;
};

But I suspect that looping isn't the best option here. Any suggestions?

EDIT: For clarity, the currentTime has to fall within the startTime and endTime

My solution: The structure of my data affords me certain benefits that allows me to simplify things a bit. I've done a basic binary search, as suggested, since the array is already sorted by startTime. I haven't fully tested the speed of this thing, but I suspect it's a fair bit faster, especially with larger arrays.

var binarySearch = function(array, currentTime) {

  var low = 0;
  var high = array.length - 1;
  var i; 

  while (low <= high) {
    i = Math.floor((low + high) / 2);

    if (array[i].startTime <= currentTime) {

      if (array[i].endTime >= currentTime ){
        // this is the one
        return array[i]._id; 

      } else {
        low = i + 1;
      }
    }

    else {
      high = i - 1;
    }
  } 

  return null;
}

解决方案

The best way to tackle this problem depends on the number of times you will have to call your search function.

If you call your function just a few times, let's say m times, go for linear search. The overall complexity for the calls of this function will be O(mn).

If you call your function many times, and by many I mean more than log(n) times, you should:

Sort your array in O(nlogn) by startTime, then by endTime if you have several items with equal values of startTime Do binary search to find the range of elements with startTime <= x. This means doing two binary searches: one for the start of the range and one for the end of the range. This is done in O(logn) Do linear search inside [start, end]. You have to do linear search because the order of startTimes tells you nothing about the endTimes. This can be anywhere between O(1) and O(n) and it depends on the distribution of your segments and the value of x.

Average case: O(nlogn) for initialization and O(logn) for each search.

Worst case: an array containing many equal segments, or segments that have a common interval, and searching in this interval. In that case you will do O(nlogn) for initialization and O(n + logn) = O(n) for search.