这听起来像你想要一个修改的二进制搜索。由于列表按排序顺序排列,二进制搜索将极大地提高线性搜索的搜索性能,并且如果对数组中项目的间距不了解,则无法比二分查找做得更好。二分法搜索将需要稍微修改,因为您不是在寻求平等,而是在没有超过的情况下尽可能接近。
下面是一个实际的算法,保持分割的搜索数据以1/2,直到它下降到仅一个元件(与上半部分或下半部分基于比较将测试值每次去):
var testData = [0,1500,5000,9348,89234,109280,109281,109283,150000];
function findNearest(data, val) {
if (!data || !data.length) {
return(null);
}
var lowest = 0, mid;
var highest = data.length - 1;
while (true) {
if (lowest == highest) {
return(lowest);
}
mid = Math.ceil(((highest - lowest)/2) + lowest);
if (data[mid] == val) {
return(mid);
}
else if (data[mid] < val) {
lowest = mid;
} else {
highest = Math.max(lowest, mid - 1);
}
}
}
而且,工作测试程序:http://jsfiddle.net/jfriend00/rWk2X/
注:此代码假设阵列中的所有值都在有序和数组不为空。
如果给它一个没有小于目标值的值的数组,它将返回0,这可能是一种特殊情况,需要处理,除非确定数组中的第一个值总是小于目标值值(例如总是零)。
如果你给它具有比目标值高出不值的数组,它会在数组中返回的最后一个值(因为它应该),这是不是一个特例,只是所需的答案。
最简单的方法:向后循环数组,并选取小于或等于播放头的第一个元素。你有没有试过,这对你的用例来说效率太低了吗? – deceze 2012-02-08 07:28:25
挑战是*有效*找到...线性搜索效率不高。 – 2012-02-08 07:31:05
尽管如此,它可能很有效*。对于现代机器来说,1500个元素不是那么重要。 – deceze 2012-02-08 07:32:48