Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.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
Javascript 循环二元索引_Javascript_Node.js - Fatal编程技术网

Javascript 循环二元索引

Javascript 循环二元索引,javascript,node.js,Javascript,Node.js,我正在构建一个工具,通过最近的时间戳连接多个流。流可能不同步,因此我将最后的n(可能>=500)项存储在固定大小的循环缓冲区中。我想使用sortedIndex(非搜索)查找缓冲区中的项目位置。我需要这个索引来查找时间戳前后的流项目 处理即将发生的问题的边缘情况并不重要,我不在乎是否返回数组外的索引或0的最大值。昨晚我在玩弄如何实现它,却找不出一个可行的实现 功能合同如下,基于() 一些测试用例(同样可以随意以不同的方式处理拐弯处的用例): function identity(x) { r

我正在构建一个工具,通过最近的时间戳连接多个流。流可能不同步,因此我将最后的
n
(可能>=500)项存储在固定大小的循环缓冲区中。我想使用
sortedIndex
搜索
)查找缓冲区中的项目位置。我需要这个索引来查找时间戳前后的流项目

处理即将发生的问题的边缘情况并不重要,我不在乎是否返回数组外的索引或
0
的最大值。昨晚我在玩弄如何实现它,却找不出一个可行的实现

功能合同如下,基于()

一些测试用例(同样可以随意以不同的方式处理拐弯处的用例):

function identity(x) {
    return x;
}

function property(prop) {
    return function(x) {
        return x[prop];
    };
}

test('sortedIndex should work on simple case', function(t) {
    var array = [1, 2, 3, 4];

    equal(sortedIndex(array, 2, identity), 1, 'equal case sorts towards left');
    equal(sortedIndex(array, 2.5, identity), 2);
    equal(sortedIndex(array, 10, identity), 0);
    equal(sortedIndex(array, -10, identity), 3);

    array = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
    equal(sortedIndex(array, {a: 2}, property('a')), 1);
    equal(sortedIndex(array, {a: 2.5}, property('a')), 2);
    equal(sortedIndex(array, {a: 10}, property('a')), 0);
    equal(sortedIndex(array, {a: -10}, property('a')), 3);
});

test('sortedIndex should work on circular collections', function() {
    var array = [2, 3, 4, 1, 1.5];

    equal(sortedIndex(array, 2, identity), 0, 'equal case sorts towards left');
    equal(sortedIndex(array, 2.5, identity), 1);
    equal(sortedIndex(array, 10, identity), 3);
    equal(sortedIndex(array, -10, identity), 2);
    equal(sortedIndex(array, 5, identity), 4);
    equal(sortedIndex(array, 3.5, identity), 3);

    array = [{a: 2}, {a: 3}, {a: 4}, {a: 1}, {a: 1.5}];
    equal(sortedIndex(array, {a: 2}, property('a')), 0, 'equal case sorts towards left');
    equal(sortedIndex(array, {a: 2.5}, property('a')), 1);
    equal(sortedIndex(array, {a: 10}, property('a')), 3);
    equal(sortedIndex(array, {a: -10}, property('a')), 2);
});

编辑---这是我完成的版本

sortedIndex:函数(值、比较器、上下文){
var low=此.start,
高=此尺寸-1;
//棘手的部分是找出它是在枢轴之前还是之后
//我们可以通过检查目标是否小于
//最后一项。之后就是典型的二进制搜索。
if(low&&comparitor.call(上下文、值、this.data[high])>0){
低=0,高=this.end;
}
while(低<高){
var mid=(低+高)>>>1;
如果(comparitor.call(context,value,this.data[mid])>0)low=mid+1;
否则高=中;
}
// http://stackoverflow.com/a/18618273/1517919
返回(((低-this.start)%this.size)+this.size)%this.size;
}
通常情况下,您会存储实际占用位置的开始和结束。有了这些信息,这应该是相当微不足道的,因为我们可以区分三种情况:

function sortedIndex(buffer, item, getValue) {
    if (buffer.start < buffer.end)
        // do standard binary search between start and end indices
    else if (getValue(buffer[0]) <= getValue(item))
        // do standard binary search between 0 and end index
    else // getValue(buffer[0] > getValue(item)
        // do standard binary search between start and buffer.length
}
函数sortedIndex(缓冲区、项、getValue){
if(buffer.start
这是我的想法(它通过了测试用例)。基本上,当数组排序时,它会执行普通的二进制搜索。当它是圆形的(例如:[2,3,4,1])时,它会找到轴(这是圆开始的索引,因此在该示例中,与数组中的4对应的索引3将是轴),然后二进制搜索枢轴所在的数组部分

 function findPivot(arr, low, high, iterable){
    // base cases
    if (high < low)  return -1;
    if (high == low) return low;

    var mid = Math.floor((low + high)/2);
    if (mid < high && iterable(arr[mid]) > iterable(arr[mid + 1]))
      return mid;
    if (mid > low && iterable(arr[mid]) < iterable(arr[mid - 1]))
      return (mid-1);
    if (iterable(arr[low]) >= iterable(arr[mid]))
      return findPivot(arr, low, mid-1, iterable);
    else
      return findPivot(arr, mid + 1, high, iterable);
 }

 function binarySearch(arr, low, high, val, iterable)
 {
    if (high < low)
        return low;
    var mid = Math.floor((low + high)/2);
    if (iterable(val) == iterable(arr[mid]))
      return mid;
    if (iterable(val) > iterable(arr[mid]))
      return binarySearch(arr, (mid + 1), high, val, iterable);
    else
      return binarySearch(arr, low, (mid -1), val, iterable);
 }


 function sortedIndex(array, value, iterable) {
     var arr_size = array.length;
    var pivot = findPivot(array, 0, arr_size-1, iterable);

    if (pivot == -1) {
      if(iterable(array[arr_size-1]) < iterable(value)){
        return 0;
      } else if(iterable(array[0]) > iterable(value)){
        return arr_size-1;
      }
      return binarySearch(array, 0, arr_size-1, value, iterable);
    }

   if(iterable(array[pivot]) < iterable(value)){
     return pivot+1;
   } else if(iterable(array[pivot+1]) > iterable(value)){
      return pivot;
   }

    if (iterable(array[pivot]) == iterable(value))
      return pivot;
    if (iterable(array[0]) <= iterable(value))
      return binarySearch(array, 0, pivot-1, value, iterable);
    else
      return binarySearch(array, pivot+1, arr_size-1, value, iterable);
    }
函数findPivot(arr、低、高、可调){
//基本情况
如果(高<低)返回-1;
如果(高==低)返回低;
var mid=数学楼层((低+高)/2);
if(中<高和可调(arr[mid])>可调(arr[mid+1]))
中途返回;
if(中>低和可调(arr[mid])=可调(arr[mid]))
返回findPivot(arr、低、中1、iterable);
其他的
返回findPivot(arr,中+1,高,可调);
}
函数二进制搜索(arr、low、high、val、iterable)
{
如果(高<低)
低回报;
var mid=数学楼层((低+高)/2);
if(iterable(val)=iterable(arr[mid]))
中途返回;
if(可调(val)>可调(arr[mid]))
返回二进制搜索(arr,(mid+1),high,val,iterable);
其他的
返回二进制搜索(arr,low,(mid-1),val,iterable);
}
函数sortedIndex(数组、值、iterable){
var arr_size=array.length;
var pivot=findPivot(数组,0,arr_size-1,iterable);
如果(枢轴==-1){
if(iterable(数组[arr_size-1])iterable(值)){
返回arr_size-1;
}
返回二进制搜索(数组,0,arr_size-1,值,iterable);
}
if(iterable(数组[pivot])iterable(值)){
返回轴;
}
if(iterable(数组[pivot])==iterable(值))
返回轴;

if(iterable(数组[0])快速评论,我认为您在测试用例中犯了一个错误;属性函数,
x
未定义,因为内部函数的参数名称不正确
prop
。在function
sortedIndex
中,您将参数取为
iterable
,并将其作为
迭代器调用。感谢您在一辆火车上写的没有测试的ide:)什么是圆形数组的“枢轴”?枢轴是它开始的索引(有点像在快速排序中),例如在[3,4,5,1,2,3]中,枢轴将是2(对应于5),我明白你的意思,但是5是它结束的地方(1是它开始的地方),如果你能想出一个迭代的
binarySearch
(像下划线一样)我会奖励你。另外,
Math.floor(x/2)
可以编写
x>>1
:)更新以添加迭代二进制搜索和findPivot
function sortedIndex(buffer, item, getValue) {
    if (buffer.start < buffer.end)
        // do standard binary search between start and end indices
    else if (getValue(buffer[0]) <= getValue(item))
        // do standard binary search between 0 and end index
    else // getValue(buffer[0] > getValue(item)
        // do standard binary search between start and buffer.length
}
 function findPivot(arr, low, high, iterable){
    // base cases
    if (high < low)  return -1;
    if (high == low) return low;

    var mid = Math.floor((low + high)/2);
    if (mid < high && iterable(arr[mid]) > iterable(arr[mid + 1]))
      return mid;
    if (mid > low && iterable(arr[mid]) < iterable(arr[mid - 1]))
      return (mid-1);
    if (iterable(arr[low]) >= iterable(arr[mid]))
      return findPivot(arr, low, mid-1, iterable);
    else
      return findPivot(arr, mid + 1, high, iterable);
 }

 function binarySearch(arr, low, high, val, iterable)
 {
    if (high < low)
        return low;
    var mid = Math.floor((low + high)/2);
    if (iterable(val) == iterable(arr[mid]))
      return mid;
    if (iterable(val) > iterable(arr[mid]))
      return binarySearch(arr, (mid + 1), high, val, iterable);
    else
      return binarySearch(arr, low, (mid -1), val, iterable);
 }


 function sortedIndex(array, value, iterable) {
     var arr_size = array.length;
    var pivot = findPivot(array, 0, arr_size-1, iterable);

    if (pivot == -1) {
      if(iterable(array[arr_size-1]) < iterable(value)){
        return 0;
      } else if(iterable(array[0]) > iterable(value)){
        return arr_size-1;
      }
      return binarySearch(array, 0, arr_size-1, value, iterable);
    }

   if(iterable(array[pivot]) < iterable(value)){
     return pivot+1;
   } else if(iterable(array[pivot+1]) > iterable(value)){
      return pivot;
   }

    if (iterable(array[pivot]) == iterable(value))
      return pivot;
    if (iterable(array[0]) <= iterable(value))
      return binarySearch(array, 0, pivot-1, value, iterable);
    else
      return binarySearch(array, pivot+1, arr_size-1, value, iterable);
    }
 function findPivot(arr, low, high, iterable)
 {
   while(true){
      // base cases
      if (high < low)  return -1;
      if (high == low) return low;

      var mid = (low + high) >>> 1;
      if (mid < high && iterable(arr[mid]) > iterable(arr[mid + 1]))
        return mid;
      if (mid > low && iterable(arr[mid]) < iterable(arr[mid - 1]))
        return (mid-1);
      if (iterable(arr[low]) >= iterable(arr[mid]))
        high = mid-1;
      else
        low = mid + 1;
   }
 }

 function binarySearch(arr, low, high, val, iterable)
 {
   while(true){
      if (high < low)
     return low;
      var mid = (low + high) >>> 1;
      if (iterable(val) == iterable(arr[mid]))
        return mid;
      if (iterable(val) > iterable(arr[mid]))
        low = mid + 1;
      else
        high = mid -1;
   }
 }


 function sortedIndex(array, value, iterable) {
    var arr_size = array.length;
    var pivot = findPivot(array, 0, arr_size-1, iterable);

    if (pivot == -1) {
      if(iterable(array[arr_size-1]) < iterable(value)){
        return 0;
      } else if(iterable(array[0]) > iterable(value)){
        return arr_size-1;
      }
      return binarySearch(array, 0, arr_size-1, value, iterable);
    }

   if(iterable(array[pivot]) < iterable(value)){
     return pivot+1;
   } else if(iterable(array[pivot+1]) > iterable(value)){
      return pivot;
   }

    if (iterable(array[pivot]) == iterable(value))
      return pivot;
    if (iterable(array[0]) <= iterable(value))
      return binarySearch(array, 0, pivot-1, value, iterable);
    else
      return binarySearch(array, pivot+1, arr_size-1, value, iterable);
 }