【问题标题】:Frequent number in JavascriptJavascript中的频繁数
【发布时间】:2016-08-23 09:07:16
【问题描述】:

在我的任务中,我必须编写一个程序来查找数组中出现频率最高的数字以及重复次数。我写了一些东西,但只打印了最大重复时间。所以我的问题是如何打印这个元素的值(最大数量)(在我的例子中是 4)? :)

var array = ['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3'];

function frequentNumber(arr) {
   var result = [],
       result2 = [];

   sorted_arr = arr.sort();

    console.log(sorted_arr);
    n=1;
    buffer = [];

    for (var i = 0; i < sorted_arr.length; i++) {

        if (sorted_arr[i + 1] === sorted_arr[i]) {
            n++;
        }else{

            if(buffer.length != 0 ){
                for(var j = 0; j < buffer.length; j++){

                    if(buffer[j] < n){
                        result = sorted_arr[j] + " is " + n;
                    }
                }
            }else{buffer.push(n)}

            n=1;
        }
    }

//    console.log(Math.max.apply(Math, buffer));
    console.log(buffer);
}

frequentNumber(array); 

【问题讨论】:

  • 添加一个保存当前最高计数的变量,并在最后打印出来。每当您发现一个比前一个计数更频繁的数字时,覆盖它。
  • 如果您有两个计数相同的值会发生什么?

标签: javascript


【解决方案1】:

您可以使用.reduce 来创建一个包含数字和时间的对象 - 然后简单地迭代该对象并找到最大值:

var ranks = array.reduce(function(totals, num) {
    if (!totals[num]) totals[num] = 0;
    totals[num]++;

    return totals;
}, {});

//Iterate and find
var max = 0;
Object.keys(ranks).forEach(function(num) {
    if (ranks[num] > max) {
        max = num;
    }
});

console.log(max); //4 - number
console.log(ranks[max]); //5 - times repeated

这不会影响具有相同计数的数字 - 在对象中首先迭代具有最高计数的数字将是结果 - 由于对象是无序的,相同的计数可能在多次执行中产生不同的结果。

【讨论】:

    【解决方案2】:

    最简单也是最正确的方法是使用原生的Array.Sort 方法。

    在循环内部,简单统计每个数字出现的频率,比较并返回。

    var arr = ['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3'];
    
    function sortByOccurence(arr) {
      return arr.sort(function(a, b) {
        var A = 0,
          B = 0;
        if (a === b) {
          return 0;
        }
        for (var i = 0; i < arr.length; i++) {
          if (arr[i] == a) {
            A++;
          }
          if (arr[i] == b) {
            B++;
          }
        }
        return B - A;
      });
    }
    console.log(sortByOccurence(arr));

    【讨论】:

    • IMO 为某人做作业会适得其反。甚至懒得解释任何事情就这样做更糟糕。
    • “最正确” - 没有意义。有些事情是正确的还是不正确的。
    • @DaveNewton 在我完成之前意外点击了帖子。我没有解决它,我只是对其进行了排序。 @Karoly Horvath,有很多方法可以解决这个问题,比如Array.reduceArray.Map 或任何数量的自定义排序函数,它们基本上重新发明了Array.Sort 功能,所以不止一个正确。此方法符合标准,这就是为什么我将其称为正确方法的原因。
    • 这个答案可能是最好的。不知道为什么 cmets 中的所有负面因素。
    【解决方案3】:

    我使用Underscore 库:

      var found = _.chain(array).countBy().pairs().max(_.last);
    
      var valueOfFrequent = found.head().value();
      var numberOfFrequent = found.tail().value();
    
      alert("number '" + valueOfFrequent + "' time of frequent: " + numberOfFrequent );
    

    试试jsfiddle中的代码

    【讨论】:

      【解决方案4】:

      我认为我对变量名的使用将有助于使其更加清晰,而无需过多评论。

      var array = ['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3'];
      var mostUsed;
      var currentNumber;
      var lastNumber;    
      var currentCount;
      var lastCount;
      function frequentNumber(arr) {
      array.sort();  
      var y = 1;
      var tempArr = [];     
          for (x = 0; x < array.length; x++){
              if(array[x] == array[y]){
                  tempArr.push(array[x]);
                  currentNumber = array[x];
              }
              else{
                  tempArr.push(array[x]);
                  currentNumber = array[x];
                  currentCount = tempArr.length;
                  //console.log(currentNumber +' occurs ' + currentCount + ' times');
                  tempArr =[];
                  if (lastCount >= currentCount){
                      mostUsed = lastNumber;
                  }
                  else{
                      mostUsed = currentNumber
                  }
                  lastCount = currentCount;
                  lastNumber = currentNumber;
      
      
              }
      
      
             y++;   
          }
          console.log('Most Used Number is = ' +mostUsed);
      }   
      frequentNumber(array);  
      

      最终发生的情况是,在对数组进行排序后,您检查第一个点 (0) 是否与第二个点 (1) 匹配,如果确实如此,您将它推入一个临时数组,该数组仅用于计数目的。当您最终到达一个不匹配的项目时,它仍会将其推入数组中,但随后会获取该数组的总长度并将其存储为 currentCount 并将正在使用的数字存储为 currentNumber。

      然后对这些变量运行另一个条件。在所有循环的第一次迭代中,没有什么要检查的,因为 are currentNumber 是最常用的数字,因为它与什么都没有比较。所以第一个数字被塞进我们将用作最常用变量的内容中。之后,我们将当前数据存储到名为 lastNumber 和 lastCount 的其他变量中。然后在此之后的每个循环中,您将当前计数与上次计数进行比较。如果 lastCount 更高,它将 lastNumber 存储为最常用的并且不会更改任何内容。但是,如果 currentNumber 更高,它将存储为最常用的数字。

      这有意义吗?如果您不遵循逻辑,则应在代码中的各个点添加 cmets,以便更好地理解它。这是您的老师进行的一次非常有趣且有趣的编码测试。我喜欢以最干净最简单的方式完成它。

      【讨论】:

        【解决方案5】:

        这是一项任务,所以我不想给你答案,但可能的解决方案可能是这样的。

        1. 用键作为数组中的数字,将值作为数组中的重复次数来实例化一个对象。所有初始计数都应为 0,并在看到每个数字时将其增加 1。

        即。最后count['4'] = 4

        1. 在遍历对象时找到最大值并保存键。

        这不是最理想的,但我相信它可以很好地完成您的任务,并且是最容易遵循的。第一个循环进行计数。第二个循环找到最大重复次数。

        【讨论】:

          【解决方案6】:

          您需要创建一个变量来保留当前的最高计数值,并在您发现更频繁的计数值时覆盖它。

          这是一个非常简单的算法。

          function getMostPopularElement(givenArray){
            var count = 1, tempCount, tempPopular;
            var popular = givenArray[0];
            for (var i = 0; i < givenArray.length - 1; i++){
              tempPopular = givenArray[i];
              tempCount = 0;
              for (var j = 1; j < givenArray.length; j++){
                if (tempPopular === givenArray[j])
                  tempCount++;
              }
              if (tempCount > count){
                popular = tempPopular;
                count = tempCount;
              }
            }
            return popular;
          }
          

          请确保如果在数组中同样遇到两个或多个值,那么下面的函数返回第一个遇到的值。它基于此tempCount &gt; count 比较。如果您在tempCount &gt;= count 上更改它,那么最受欢迎的值将是最后遇到的值。

          【讨论】:

            【解决方案7】:

            您可以使用哈希表进行计数,并使用Array#reduce 在单个循环中获取它的最大计数值。

            max 的结果是一个数组,因为原始数组可能包含相同计数的值。

            var array = ['13', '4', '1', '1', '4', '2', '3', '4', '4', '1', '2', '4', '9', '3'],
                count = Object.create(null),
                max = array.reduce(function (r, a, i) {
                    count[a] = (count[a] || 0) + 1;
                    if (!i || count[a] > count[r[0]]) {
                        return [a];
                    }
                    if (a !== r[0] && count[a] === count[r[0]]) {
                        r.push(a);
                    }
                    return r;
                }, undefined);
            
            console.log(max);
            console.log(count);

            【讨论】:

            • 如果结果从高到低排序,这可能是最好的答案。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-20
            • 2021-04-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-19
            相关资源
            最近更新 更多