使用Javascript查找范围值的索引

时间:2014-04-16 16:46:02

标签: javascript algorithm

给出以下范围和索引:

index   from        to
11      24          48
10      12          24
9       6           12
8       3           6
7       1.5         3
6       0.75        1.5
5       0.375       0.75
4       0.1875      0.375
3       0.09375     0.1875
2       0.046875    0.09375
1       0.0234375   0.046875
0       0.015625    0.0234375

我应该如何组织这个(数据/算法)以获得类似的东西:

x=0.22;
n=findIndex(x);
alert(n);

// output 4

显然它可以适用于任何大小的索引。我唯一想到的就是嵌套ifs ......

THX。

3 个答案:

答案 0 :(得分:4)

我会写这样的东西:

var indexes = {
  11 : [24, 48], 
  10 : [12, 24],
  9 : [6, 12],
  8 : [3, 6],
  7 : [1.5, 3],
  6 : [0.75, 1.5],
  5 : [0.375, 0.75],
  4 : [0.1875, 0.375],
  3 : [0.09375, 0.1875],
  2 : [0.046875, 0.09375],
  1 : [0.0234375, 0.046875],
  0 : [0.015625, 0.0234375]
};

var x = 0.22;
var n = findIndex(x);

function findIndex(d){
    for(var key in indexes){
    if(d >= indexes[key][0] && d <= indexes[key][1]) 
      return key;
     }
}
alert(n);

Fiddle

可能不是最有效的代码,对改进感到高兴。

答案 1 :(得分:2)

在索引范围上使用binary Search并检查该点是否在给定索引范围内或两侧。

答案 2 :(得分:1)

由于看起来数组已经排序,为什么不使用二进制搜索算法。我使用二进制搜索将jsfiddle放在一起,并且匹配条件假设包含&#34;来自&#34;。换句话说,6匹配9而不是8。

ranges = [
    {from: .015625, to: .0234375},
    {from: .0234375, to: .046875},
    {from: .046875, to: .09375},
    {from: .09375, to: .1875},
    {from: .1875, to: .375},
    {from: .375, to: .75},
    {from: .75, to: 1.5},
    {from: 1.5, to: 3},
    {from: 3, to: 6},
    {from: 6, to: 12},
    {from: 12, to: 24},
    {from: 24, to: 48}
];


//A function that can build an array of ranges
//by doubling the seed... This looks to produce a
//different results than your ranges as 
// .0234375 is not twice .015625.
var buildRanges = function (seed, maxIndex) {
    var tmp = [];
    var curr = 0;
    var from = seed;
    var to = 2 * from;
    while (curr <= maxIndex) {
        tmp.push({from: from, to: to});
        from = to;
        to = 2 * from;
        curr++;
    }

    return tmp;
}

var findIndex = function (x) {
    var min = 0;
    var max = ranges.length - 1
    var mid;
    while (min <= max) {
        mid = parseInt((max + min) / 2);
        //Assume "from" field is inclusive
        if (x >= ranges[mid].from && x < ranges[mid].to) {
            return mid;
        }
        //We know that maximum must be adjusted below mid
        else if (x < ranges[mid].from) {
            max = mid - 1;
        }
        //Else we must move up the min
        else {
            min = mid + 1;
        }
    }
}

alert(findIndex(.22)); //4
alert(findIndex(6)); //9
alert(findIndex(12)); //10
alert(findIndex(.9)); //6