javascript-循环二进制索引
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript-循环二进制索引,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6104字,纯文字阅读大概需要9分钟。
内容图文
![javascript-循环二进制索引](/upload/InfoBanner/zyjiaocheng/679/7eccdbce0ac2438185e7770bd3f801cf.jpg)
我正在构建一个工具,可以在最近的时间戳之前加入多个流.这些流可能不同步,因此我将最后n个(可能> == 500)项目存储在固定大小的循环缓冲区中.我想使用sortedIndex(而不是搜索)来查找项目在缓冲区中的放置位置.我需要此索引来在时间戳之前和之后找到流项目.
处理即将来临的问题的极端情况并不重要,我不在乎是否在数组之外返回索引,或者对于最大值返回0.昨晚我一直在执行此实现,无法找到可行的实现.
以下是功能合同,其基于_.sortedIndex(implementation)
/**
* Binary search for finding the closest computed (by iterator) value
* in some sorted circular array
*
* @param {Array} array a circular array-like
* @param {Object} value to search for an index
* @param {Function} iterator to compute the compare value of an item
*/
function sortedIndex(array, value, iterator) {
var low = 0,
high = array.length;
while (low != high && iterator(array[low]) > iterator(array[high])) {
// The binary search I failed to implement
}
return low;
}
一些测试用例(同样可以随意处理拐角处的不同情况):http://jsbin.com/yusilaba/1/edit
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);
});
编辑—这是我完成的版本https://github.com/trevnorris/cbuffer/pull/14
sortedIndex : function(value, comparitor, context) {
var low = this.start,
high = this.size - 1;
// Tricky part is finding if its before or after the pivot
// we can get this info by checking if the target is less than
// the last item. After that it's just a typical binary search.
if (low && comparitor.call(context, value, this.data[high]) > 0) {
low = 0, high = this.end;
}
while (low < high) {
var mid = (low + high) >>> 1;
if (comparitor.call(context, value, this.data[mid]) > 0) low = mid + 1;
else high = mid;
}
// https://stackoverflow.com/a/18618273/1517919
return (((low - this.start) % this.size) + this.size) % this.size;
}
解决方法:
这就是我想出的(它通过了您的测试用例).基本上,对数组进行排序时,它会执行常规的二进制搜索.当它是圆形时(例如:[2,3,4,1]),它找到枢轴(这是圆的起始位置的索引,因此在该示例中,索引3与数组中的4对应)将是枢轴),然后二进制搜索枢轴所在的数组部分.
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);
}
这是测试用例:http://jsbin.com/ratufewa/1/edit
希望这是正确的方向.
迭代解决方案http://jsbin.com/ratufewa/3/edit:
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);
}
内容总结
以上是互联网集市为您收集整理的javascript-循环二进制索引全部内容,希望文章能够帮你解决javascript-循环二进制索引所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。