数组中的数字序列数

时间:2019-02-06 18:26:26

标签: javascript arrays

如果我的数组看起来像

[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;

这是我目前拥有的,我相信它应该可以工作,但是我觉得有一种更优化的方法可以做到这一点。

谢谢!

3 个答案:

答案 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}`);