在我的任务中,我必须编写一个程序来查找数组中最频繁的数字以及它重复的次数。我写了一些东西,但只打印最大重复次数。所以我的问题是如何打印这个元素的值(最大值((在我的情况下是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);
您可以使用.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
这并不考虑具有相同计数的数字——无论哪个数字在对象中首先迭代,计数最高,都将是结果——而且由于对象是无序的,相同的计数在多次执行中可能会有不同的结果。
最简单、最正确的方法是使用本机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));
我使用Undercore库:
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
我认为我对变量名的使用将有助于使其更加清晰,而无需过多注释。
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更高,它将把它存储为最常用的数字。
这有道理吗?如果你不遵循逻辑,你应该在代码的各个点添加注释,这样你就能更好地理解它。这是你的老师做的一个很好的、有趣的编码测试。我喜欢用最干净、最简单的方式完成它。
这是一项任务,所以我不想给你答案,但可能的解决方案可能是这样的。
- 实例化一个对象,其中键是数组中的数字,值是数组中重复次数。所有初始计数都应该是0,当您看到每个数字时,您可以将其增加1
即。CCD_ 2。
- 查找最大值并在循环遍历对象时保存关键帧
这不是最理想的,但我相信它会在你的任务中做得很好,而且是最容易遵循的。第一个循环进行计数。第二个循环查找最大重复次数。
您需要创建一个保持当前最高计数值的变量,并在找到更频繁的计数值时覆盖它。
下面是一个非常简单的算法。
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 > count
的比较。如果您在tempCount >= count
上更改它,那么最流行的值将是最后一个加密的值。
您可以使用哈希表进行计数,并使用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);