【问题标题】:find top k elements in array查找数组中的前 k 个元素
【发布时间】:2015-02-20 14:45:23
【问题描述】:

我有一个格式如下的数组:

var series = [[horse,1],[cat,2],[dog,4],[dragon,4],[cow,6]]

为了根据第二个参数找到前 3 个元素,我对数组进行了排序。所以为此我使用下面的代码:

 series.sort( function(a,b) {
        if (a[1] === b[1]) {
            return 0;
    }
    else {
         return (a[1] < b[1]) ? 1 : -1;
    }
});

效果很好。然后,如果我想找到前 3 个,我总是可以选择 [0,2]。但是,如果第 4 个值等于第 3 个值,那么我会错过它。在这种情况下,如果我要求前 3 个输出应该是 [[horse,1],[cat,2],[dog,4],[dragon,4] 因为dragon 和 dog 具有相等的值 (4)。所以,我想知道是否有一些我可以开箱即用的库或一些有效的算法来返回前 3 个值,这不一定意味着返回前 3 个元素数组?

【问题讨论】:

  • 您不能手动检查第 3、第 4(等)元素,如果它们的值相等则添加到结果数组中?
  • 大声笑,可能还有另外 1000 个具有相同值的元素..我不知道会有多少
  • 如果您希望低数字排在第一位,则您的排序是倒退的。
  • 是的,没错。这只是一个例子。

标签: javascript jquery arrays


【解决方案1】:

只需建立一个列表:

var top = [];
top.push(series[0]);
top.push(series[1]);
for (var i = 2; i < series.length && series[i][1] == series[2][1]; ++i)
  top.push(series[i]);

概括一下(稍微):

function top(series, k) {
  var top = [];
  for (var i = ; i < k - 1; ++i)
    top.push(series[i]);
  for (; i < series.length && series[k-1][1] == series[i][1]; ++i)
    top.push(series[i]);
  return top;
}

【讨论】:

  • 为什么一开始只推送k-1元素到列表中?
  • 哦,我明白了。第一次通过循环,i == k-1,所以series[k-1] == series[i]``,if保证成功。恕我直言,这似乎是不必要的混乱。
  • 因为列表已排序(大概;要真正正确概括这一点需要重新考虑整个设置),所以很明显,我们总是希望列表中没有那么多。这些元素的“值”是什么并不重要。
  • 我明白这一点。我只是想知道为什么第一个循环是i &lt; k-1 而不是i &lt; k
  • @Barmar 是的,我同意这令人困惑,但这是一个令人困惑的前提。对于较长的列表和相对较短的 k ,最好只通过列表进行一次线性传递并省去排序。 编辑或两遍可能
【解决方案2】:
var series = [["horse",1],["cat",2],["dog",4],["dragon",4],["cow",6]]
num = 3;
var arr = [];
for(var i=0; i<series.length; i++)
{
var curr = series[i][1];
var next = series[i][1];
    if(i<num)
    {
     arr.push(series[i]);
    }
    else if(curr==next)
    {
     arr.push(series[i]);
        break;
    }    
}
console.log(arr);

【讨论】:

    【解决方案3】:

    所以我会创建第二个数组(长度为 3)并循环遍历初始数组。 When 前三个项目应该自动添加到数组中。然后,当我们遍历第一个数组并找到高于最小值的值时,我们删除最小值并将新项放在新数组中的适当位置。

    var series = [[horse,1],[cat,2],[dog,4],[dragon,4],[cow,6]];
    function top3(a){
      // Create a new Array to hold the top values
      var top = [a[0], a[1], a[2]]; // Initialize it with the first three items
      for(var i=3;i<a.length;i++){
        /* Find the minimum value and its position */
        var min = top[0][1];
        var min_pos = 0;
        for(var e=1;e<3;e++){
          if(top[e][1]<min){
            min = top[e][1];
            min_post = e;
          }
        }
        /* If larger than the top arrays minimum */
        if( a[i][1] > min ){
          /* remove the top arrays min */
          top.splice(min_pos, 1);
        }
        /* Add the new item into the top array */
        top.push(a[i]);
      }
      /* Now our "top" array has the items with the top 3 values, if you want them sorted use a bubble sort here, if not just return "top" */
      bubbleSortByIndex(a, 1); // Sorts by the second item in an array or arrays
      return top;
    };
    /*
        Bubble Sort Algorythm adapted from http://en.wikipedia.org/wiki/Bubble_sort
    */
    function bubbleSortByIndex(a, i){
      var swapped;
      do {
        swapped = false;
        for(var e=1;e<a.length-1;e++){
          if( a[e-1][i] > A[e][i]){
            swapped = true;
            var temp = a[e-1];
            a[e-1] = a[e];
            a[e] = temp
          }
        }
      } while (swapped);
      return a;
    }
    top3(series);
    

    这会保留原始数组并仅找到前三个项目,并对它们进行排序。如果您希望对整个原始数组进行排序,则只需调用 bubbleSortByIndex(series, 1) 并忽略整个“top3()”函数。

    【讨论】:

      猜你喜欢
      • 2021-12-24
      • 2021-01-13
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 2021-05-16
      • 2019-03-12
      相关资源
      最近更新 更多