我是JavaScript的初学者,我正在尝试编写用于查找模式的代码。我的代码正在运行,但它只有在连续编写时才能找到模式。但是当有像这样的a = [1,2,3,4,5,2]
数组时,它找不到模式。
因为我是一个初学者,我不想写任何复杂的东西,而是想用最简单的方法来学习它。有人能在这方面帮我吗?
list = [1,2,3,4,5,6,7,7]
var empty = []
i = 0
max = 0
while (i<list.length){
if (list[i]==list[i+1]){
empty = list[i]
i += 1
}else{
i +=1
}
}
document.write(empty)
发布于 2018-10-20 03:16:07
您的代码假设参数数组是预先排序的,这是一个有风险且有局限性的假设,而且似乎只适用于已排序的数组(反例:[1,1,1,7,7]
错误地将7
报告为模式)。
如果您希望坚持这种方法,那么您就走在了正确的轨道上,但是您需要跟踪当前/最佳条纹、当前/最佳元素,并在返回结果之前执行最长条纹的最终检查:
var mode = a => {
a = a.slice().sort((x, y) => x - y);
var bestStreak = 1;
var bestElem = a[0];
var currentStreak = 1;
var currentElem = a[0];
for (let i = 1; i < a.length; i++) {
if (a[i-1] !== a[i]) {
if (currentStreak > bestStreak) {
bestStreak = currentStreak;
bestElem = currentElem;
}
currentStreak = 0;
currentElem = a[i];
}
currentStreak++;
}
return currentStreak > bestStreak ? currentElem : bestElem;
};
console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));
话虽如此,排序是一个非线性操作,所以我建议尝试另一种方法。
其思想是使用一个对象为数组中的每个项目保留一个出现次数的计数,然后获取计数最高的元素。我使用reduce
来执行这两个操作:
const mode = a =>
Object.values(
a.reduce((count, e) => {
if (!(e in count)) {
count[e] = [0, e];
}
count[e][0]++;
return count;
}, {})
).reduce((a, v) => v[0] < a[0] ? a : v, [0, null])[1];
;
console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));
或者,同样的事情,为了可读性而不使用reduce
编写:
const mode = a => {
const count = {};
a.forEach(e => {
if (!(e in count)) {
count[e] = 0;
}
count[e]++;
});
let bestElement;
let bestCount = 0;
Object.entries(count).forEach(([k, v]) => {
if (v > bestCount) {
bestElement = k;
bestCount = v;
}
});
return bestElement;
};
console.log(mode([1,2,3,4,5,6,7,7]));
console.log(mode([1,1,1,4,5,6,7,7]));
console.log(mode([1,2,3,3,3,6,3,7]));
console.log(mode([1,3,3,4,5,2,2,1]));
console.log(mode([]));
请注意,在平局的情况下,这些方法不会选择相同的模式。您可能希望添加一个数组来跟踪所有模式,或者更改算法以选择第一个或最后一个出现的模式来满足您的需要。
发布于 2018-10-20 04:21:25
使用散列
list = [1,2,3,4,5,6,7,7]
counts = {}
list.forEach(function(e) {
if(counts[e] === undefined) {
counts[e] = 0
}
counts[e] += 1
})
这将导致以下结果:
{1:1,2:1,3:1,4:1,5:1,6:1,7:2}
这个相关的问题涉及在散列中查找最大值和最小值,这实际上是您在结束时要做的事情。
Fast way to get the min/max values among properties of object
https://stackoverflow.com/questions/52898456
复制相似问题