使用Javascript查找数组中是否包含5个连续数字

4

我有一个包含数字的已排序数组。我想要检查这个数组(或类似的数组)是否包含5个连续的数字。

注意:该数组可能包含重复和双位数数字。

我尝试过下面的方法,但是失败了。

var array = [1,3,5,7,7,8,9,10,11]
var current = null;
var cnt = 0;
for (var i = 0; i < array.length; i++) {
    if (array[i] != current) {
        if (cnt > 4) {
            return true;
        }
        current = array[i];
        cnt = 1;
    } else {
        cnt++;
    }

}
if (cnt > 4) {
    return true;
}

}

可以给一个示例输入和预期答案吗? - Mritunjay
你尝试过什么?我的方法大致是这样的:遍历数组,存储当前值,如果下一个值与当前值相同,则增加计数器。如果它们不同,则将计数器重置为0。 - James Taylor
请在此文章中查找内容:http://www.geeksforgeeks.org/check-if-array-elements-are-consecutive/ - Vikrant
这个是在函数内定义的吗?不确定return true应该放在哪里,或者你如何查看结果。此外,当它遇到两个7时,cnt只会增加一次。 - Christian Hain
“Consecutive”是什么意思?在您的示例数据中,数字并不是“连续的”,它们只是单调递增的。在五个一排中,重复的数字是否计入统计,还是跳过不计? - user663031
7个回答

3
一个迭代、直接的方法是:
var should_be_true = [1,3,5,7,7,8,9,10,11];
var should_be_false = [1,3,5,7,9,11,13,15,17];

var testArray = function(array) {
    var conseq = 1;
    for (var idx = 1; idx < array.length ; idx++) {
        if (array[idx] == array[idx-1] + 1)
            conseq++;
        else
            conseq = 1;
        if (conseq == 5)
            return true;
    }
    return false;
}

console.log(testArray(should_be_true)); //true
console.log(testArray(should_be_false)); //false

为了更有趣,这里是一个函数式方法的变化版本,返回序列开始的位置,如果没有足够长的序列存在则返回-1:

should_be_true.map(function(curr,idx,arr) {
    return (curr == arr[idx-1] +1) ? 1 : 0;
}).join('').search(/1{4}/); 

3

一个功能性的方法是

function fiveInARow(array) {

  // compare if one element is greater than or equal to the previous one
  function compare(elt, i, arr) { return !i || elt >= arr[i-1]; });

  // check if at a given position, every one of the last five comparisons is true
  function check (_, i, greaters) { 
    return i >= 4 && greaters.slice(i-4, i) . every(Boolean);                         
  }

  return array . map(compare) . some(check);
}

这里的逻辑是首先使用map创建一个布尔数组,显示每个元素是否大于或等于前一个元素。这将产生一个数组,例如[true, true, true, false, true]

some部分询问任何元素,它是否与前面四个元素都为true?如果是,则返回true

递归解决方案

递归解决方案可能更容易阅读。
function fiveInARow(array) {

  return function _five(array, prev, n) {
    if (n >= 5)        return true;
    if (!array.length) return false;

    var next = array.shift();
    return _five(array, next, next === prev ? n : next >= prev ? n+1 : 0);
  }(array, -999999, 5);

}

0
var array = [1,3,5,7,7,8,9,10,11];
var cons=false;
var count=0;
for(i=0;i<array.length;i++){
    if(array[i]+1==array[i+1]){
        count++;
    }
    else{
        count=0;
    }
    if(count==4){
        cons=true;
    }
}
if(cons){
    //do what you want with it
}

演示

更加优雅的方式是将整个内容定义为以下函数:

function checkCons(array){
    var cons=false;
    var count=0;
    for(i=0;i<array.length;i++){
        if(array[i]+1==array[i+1]){
            count++;
        }
        else{
            count=0;
        }
        if(count==4){
            cons=true;
        }
    }
    return cons;
}

然后像这样使用它:

var array = [1,3,5,7,7,8,9,10,11];
if(checkCons(array)){
    //do what you want with it
}

演示


0
   function fiveStraight() {
       var array = [1, 3, 5, 7, 7, 8, 9, 10, 12];
       var prev = array[0];
       var numberOfStraight = 1;

       for (var i = 1; i < array.length; i++) {
           numberOfStraight = array[i] === prev + 1 ? numberOfStraight + 1 : 1;
           prev = array[i];
           if (numberOfStraight === 5) return true;
       }

       return false;
   }

JSFIDDLE


在进行连续顺序检查之前,检查每个索引的5+是否更有效率? - prasanthv
我不这么认为。 最坏情况是遍历整个数组。最好的情况是连续数字出现在第一个位置。我从开头开始向结尾走。如果我找到了一组连续数字,我就返回true。如果没有,并且我已经到达了末尾,我就返回false。我不知道如何改进这种方法。 - Amir Popovich
实际上,这是一个有趣的问题。你可以通过只读取每个第二个位置(将索引增加2而不是1)来大致提高此搜索的效率。如果两个值相差2,则返回并检查中间的值。这样做可以避免一些不必要的读取...在没有序列的情况下,可以减少n/2次读取。 - S McCrohan

0

使用此代码,您可以查找给定数字的连续最高次数或查找一般情况下的连续最高次数

var findMaxConsecutiveOnes = function (arr, number) {
   //check for boundries
   if(!number || !arr.length) return;

  // maximum number of consectuives
  let max = 0;

  // count homy many consecutives before it ends (why it's 1 ? because a lonely number is still counted)
  let counter = 1;

  // you can ignore the next 2 variable if you want to use for loop instead of while
  let length = arr.length;
  let i = 1; // counting from index 1 because we are checking against index-1
  while (i < length) {

    if (arr[i] == arr[i - 1]) {

      // boom, we have a consecutive, count it now
      counter++;
    } else {

      // rest to 1
      counter = 1;
    }

    // always update the max variable to the new max value
    max = Math.max(counter, max);

    //for the sake of iteration
    i++;
  }
  return max== number;
};
console.log(findMaxConsecutiveOnes([5, 5, 5, 1, 1, 1, 1, 1]));

抱歉,这是我的第一次回答:D 我会进行编辑。 - scr2em

0

这是我发现的最直接的方法。无论是降序还是升序的值都算作连续的(如果不是这种情况,请尝试调整Math.abs()的调用)。

function consecutiveValuesCount(array) {
    // sort the values if not pre-sorted
    var sortedValues = array.sort();

    // the result variable / how many consecutive numbers did we find?
    // there's always atleast 1 consecutive digit ...
    var count = 1;
    for (var i = 0; i < sortedValues.length - 1; i++) {
        // both descending and ascending orders count as we are using Math.abs()
        if (Math.abs(sortedValues[i] - sortedValues[i+1]) == 1) {
          ++count;
        }
    }
    return count;
}

//input
var array = [1,2,4,5,3];
// output
5

-3

cnt 只会在遇到两个 7 的时候增加一次。

将递增行放在真条件中,将重置行放在 else 语句中。

// Put into a function for testing.
function foo() {
  var array = [1, 3, 5, 7, 7, 8, 9, 10, 11]
  var current = null;
  var cnt = 0;

  for (var i = 0; i < array.length; i++) {
    // Also need to make sure the next array item is a consecutive increase.
    if (array[i] != current && array[i] === array[i-1] + 1) {
      if (cnt > 4) {
        return true;
      }

      current = array[i];
      cnt++;
    } else {
      cnt = 1;
    }
  }

  if (cnt > 4) {
    return true;
  } else {
    return false;
  }
};

// Call function.
alert(foo());


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接