如果我的数组看起来像
[0, 2, 4, 10, 10, 10, 10, 2, 5, 3, 2, 10, 10, 5, 7, 4, 10, 10, 10, 10]
如果序列10's
至少出现3次,我如何计算该序列的次数。
因此在这种情况下,输出将为2
,因为有2个10的顺序,每个连续10个。
const values = [0, 2, 4, 10, 10, 10, 10, 2, 5, 3, 2, 10, 10, 5, 7, 4, 10, 10, 10, 10];
const MAX = 10;
const threshold = 3;
let count= 0;
let numberInSeq = 0;
values.forEach(x => {
if (x === MAX) {
numberInSeq++;
} else {
if (numberInSeq >= threshold) {
count++
}
numberInSeq = 0;
}
})
return count;
这是我目前拥有的,我相信它应该可以工作,但是我觉得有一种更优化的方法可以做到这一点。
谢谢!
答案 0 :(得分:2)
您的forEach
循环中有一些小错误。如果当前值与检查值匹配,即您的情况下为MAX
,则需要检查阈值 ,如果达到阈值,则需要重置numberInSeq
。这样可以正确计数序列。我还为长序列添加了标志变量sequenceFound
,因此它们的计数不会超过一次。
此方法的优势在于它是一次通过,这意味着在Big O表示法中,与多次通过解决方案相比,它仅是O(n)
复杂度。
var sequenceFound = false;
values.forEach(x => {
if (x === MAX) {
numberInSeq++;
if (numberInSeq >= threshold && sequenceFound === false) {
count++;
sequenceFound = true;
numberInSeq = 0;
}
} else {
numberInSeq = 0;
sequenceFound = false;
}
});
答案 1 :(得分:1)
一种方法 是使用一个字符将arr连接到字符串,然后使用正则表达式匹配10 followed by that character
,然后检查每个匹配的长度并将其减少为单个值
let arr = [0, 2, 4, 10, 10, 10, 10, 2, 5, 3, 2, 10, 10, 5, 7, 4, 10, 10, 10, 10]
let op = arr
.join('-')
.match(/(10-)+/g)
.reduce((o,e)=> (o = e.split('-').length-1 >= 3 ? o+1 : o) , 0)
console.log(op)
旁注 -在使用for循环方面,现在绝对是性能方面的问题。
答案 2 :(得分:0)
这是使用正则表达式的一种方式:
/, 10{3,}/g
所有条件都在该正则表达式中,但必须先将数组转换为字符串。如果效率不高,那就不一样了。
let val = [0, 2, 4, 10, 10, 10, 10, 2, 5, 3, 2, 10, 10, 5, 7, 4, 10, 10, 10, 10];
let str = val.join(', ');
let i = 0;
const rgx = /(, 10){3,}/g;
let res = rgx.exec(str);
while (res !== null) {
i++;
console.log(res[0]);
res = rgx.exec(str);
}
console.log(`count: ${i}`);