【问题标题】:Getting the value from key in a dictionary that is nearest to a given number using JavaScript使用 JavaScript 从最接近给定数字的字典中的键中获取值
【发布时间】:2009-10-29 22:10:17
【问题描述】:

我有一本字典(键是整数,值是浮点数)。我现在要向字典询问大于给定数字但小于下一个更大键的键的值。

例子:

dict = {100: 0.0035, 150: 0.0024, 200: 0.0019}。

我给 122,它应该给我 0.0035

我给 333,它应该给我 0.0019

我给 200,它应该给我 0.0024

谢谢!

【问题讨论】:

  • 在您的示例中,200 大于键 150 但不小于键 200,那么应该为 200 检索哪个值?
  • 如果我给数字 200 结果应该是 0.0024,当我给数字 201 结果应该是 0.0019。

标签: javascript jquery dictionary


【解决方案1】:

这是二叉树的完美用例。对于堆栈溢出答案,这个主题有点宽泛,但无论如何都可以。

function addValueToNode(tree, nodeidx, value) {
    var left = 2*nodeidx + 1;
    var right = 2*nodeidx + 2;

    if(value > tree[nodeidx]) {
        if(!tree[right])
            tree[right] = value;
        else
            addValueToNode(tree, right, value);
    } else {
        if(!tree[left])
            tree[left] = value;
        else
            addValueToNode(tree, left, value);
    }
}

function addValueToTree(tree, value) {
    if(tree.length == 0)
        tree.push(value)
    else
        addValueToNode(tree, 0, value);
}

function addValuesToTree(tree, values) {
    for(var i = 0; i < values.length; i++)
        addValueToTree(tree, values[i]);
}

function addDictionaryToTree(tree, dict) {
    var values = [];
    for(var key in dict) {
        values.push(key);
    }
    values.sort();
    addValuesToTree(tree, values);
}

function findClosestValue(tree, nodeidx, value) {
    var left = 2*nodeidx + 1;
    var right = 2*nodeidx + 2;

    if(value > tree[nodeidx]) {
        if(!tree[right] || tree[right] == value)
            return tree[nodeidx];
        else
            return findClosestValue(tree, right, value);
    } else {
        if(!tree[left])
            return tree[nodeidx];
        else
            return findClosestValue(tree, left, value);
    }
}
var tree = [];
var dict = {100: 0.0035, 150: 0.0024, 200: 0.0019};

addDictionaryToTree(tree, dict);

var closest = findClosestValue(tree, 0, 175);
var dictValue = dict[closest];

alert( closest + " : " + dictValue);

【讨论】:

    【解决方案2】:

    工作示例(在 Firefox 3.6 下测试):

    <html>
    <head>
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
    var dict = {100: 0.0035, 150: 0.0024, 200: 0.0019};
    
    function r(aNum) {
        var result;
    
        for (var key in dict) {
            var dist = key - aNum
    
            if ((dist < 0 && dist < result) || result === undefined) {
                result = key;
            }
        }
    
        return dict[result];
    }
    
    $(document).ready(function() {
        $('li').each(function() {
            var id = $(this).attr('id').replace('n', '')
            $(this).html(id + ": " + r(id));
        });
    });
    </script>
    </head>
    <body>
        <ul>
            <li id="n122"></li>
            <li id="n333"></li>
            <li id="n200"></li>
        </ul>
    </body>
    </html>
    

    【讨论】:

    • $(this).html(id + ": " + s(id)); 你可能是指$(this).html(id + ": " + r(id));
    【解决方案3】:
    var value = 122;
    var min = null;
    var minkey = null;
    for ( var key : dict ) {
      if (min==null || abs(value-key)<min) {
          min=abs(value-key);
          minkey = key;
      }
    }
    return dict[minkey]
    

    你可以试试这个。对不起,我没有机会测试它。

    【讨论】:

    • var key : dict 你可能是指var key in dict ...除此之外,它应该可以解决问题。
    • 不起作用:输出 122>0.0035, 333>0.0019, 200>0.0019 注意 abs 应该是 Math.abs
    【解决方案4】:

    以下功能符合您的要求:

    function getNumber(dict, value) {
      var key, found;
    
      for (key in dict) {
        if (value - key > 0) {
          found = key;
        }
      }
      return dict[found];
    }
    
    var dict = {100: 0.0035, 150: 0.0024, 200: 0.0019};
    
    // Firebug assertions
    console.assert(getNumber(dict, 122) == 0.0035);
    console.assert(getNumber(dict, 333) == 0.0019);
    console.assert(getNumber(dict, 200) == 0.0024);
    

    【讨论】:

      【解决方案5】:

      二分搜索,使用修改后的(稳定的)算法搜索满足比较条件的最小元素。

      【讨论】:

        【解决方案6】:

        如果您的字典不是很大,您可以尝试从例如 (122-1) 循环。如果它是未定义的,减 1 并重试,直到你找到一些东西:)

        【讨论】:

          猜你喜欢
          • 2016-03-20
          • 2012-08-21
          • 1970-01-01
          • 2021-05-25
          • 1970-01-01
          • 2015-04-24
          • 1970-01-01
          相关资源
          最近更新 更多