在数组中找到相同数字的最长连续出现次数

7
使用JavaScript,我正在尝试找到一种方法来查找数组中相同数字(在本例中为1)的最长出现次数。
例如,这是一个示例数组: [2,5,3,1,1,1,3,7,9,6,4,1,1,1,1,1,4,7,2,3,1,1,4,3] 我想编写一个函数,它将返回“5”,因为数字1连续出现了5次。 (它也连续出现了3次和2次,但我想要最长的出现次数)。
到目前为止,我已经编写了:
function streak(arr) {
    var i,
        temp,
        streak,
        length = arr.length;

    for(i=0; i<length; i++) {
        if (arr[i] === 1) {
            streak += 1;
        } else {
            temp = streak;
            break;
        }
    }
}

我知道如果我找到了一个事件,就需要有一种方法来知道我上次处理到哪里,但我感觉有些困惑。

有什么指导意见吗?


3
这有帮助吗?https://dev59.com/_G035IYBdhLWcg3wBLTb - stripthesoul
12个回答

7

我稍微修改了你的函数。你需要将最高连胜存储为一个单独的变量,与当前连胜分开,并在循环中必要时覆盖它 - 最后在函数末尾返回该变量。

function streak(arr) {
    var i,
        temp,
        streak,
        length = arr.length,
        highestStreak = 0;

    for(i = 0; i < length; i++) {
        // check the value of the current entry against the last
        if(temp != '' && temp == arr[i]) {
            // it's a match
            streak++;
        } else {
            // it's not a match, start streak from 1
            streak = 1;
        }

        // set current letter for next time
        temp = arr[i];

        // set the master streak var
        if(streak > highestStreak) {
            highestStreak = streak;
        }
    }

    return highestStreak;
}

var array = [2,5,3,1,1,1,3,7,9,6,4,1,1,1,1,1,4,7,2,3,1,1,4,3];

console.log(streak(array)); // 5

如果您还想跟踪最高连胜的价值,请在函数开始时定义另一个变量,在保存最高连胜时保存其值,并将其作为数组返回:

    // set the master streak var
    if(streak > highestStreak) {
        highestStreakValue = temp;
        highestStreak = streak;
    }
}

return [highestStreak, highestStreakValue];


var array = [2,5,3,1,1,1,3,7,9,6,4,'a','a','a','a','a',4,7,2,3,1,1,4,3];
console.log(streak(array)); // [5, "a"]

演示同时返回结果的代码


2

另一种方法是将数组转换为字符串。正则表达式使用反向引用,确保仅匹配相同字符的序列。并且当 execg 标志一起使用时,重复执行将从上次匹配的末尾而不是开头继续。

var arr = [2,5,3,1,1,1,3,7,9,6,4,1,1,1,1,1,4,7,2,3,1,1,4,3];
var str = arr.join('');
var regex = /(.)\1*/g;
var match;
var largest = '';

while (match = regex.exec(str)) {
  largest = match[0].length > largest.length ? match[0] : largest;
}

console.log(largest.length);

1

另一种方法是使用正则表达式并将数组转换为字符串。

var arr = [2,5,3,1,1,1,3,7,9,6,4,1,1,1,1,1,4,7,2,3,1,1,4,3];
var str = arr.join('').match(/1+/g);
console.log(process ? process.sort().pop() : "No ocurrences");

1

你的问题:

  • 你没有存储当前连胜记录
  • 你没有指定何时streak超过旧的连胜记录

使用这个:

function streak(arr) {
    var i,
        temp,
        streak = 1,
        maxStreak = 0,
        prevNumber,
        length = arr.length;

    for(i=1; i<length; i++) {
        prevNumber = arr[i-1];
        if (arr[i] == prevNumber) {
            streak += 1;
        } else {
            if(streak > maxStreak) {
                maxStreak = streak;
                streak = 1;
            }
        }
    }
    return maxStreak;
}

演示


1
你需要另外两个数组。
  1. 使用循环将源数组中的不同数字存储到第一个数组中
  2. 创建第二个数组,长度与第一个数组中的不同数字数量相等
  3. 使用第一个数组的长度进行循环,并根据其索引将值推送到第二个数组中
  4. 再次使用第二个数组进行循环,并使用第二个数组的索引找到最常出现的数字
  5. 最后,使用步骤4获取的索引从第一个数组中获取数字。

我没有为您编写代码,因为您只是要求一些提示。


1
你可以使用 Array#reduce 方法,返回相同项序列的开始索引。然后检查和更新计数器,如果项目不相等。

var array = [2, 5, 3, 1, 1, 1, 3, 7, 9, 6, 4, 1, 1, 1, 1, 1, 4, 7, 2, 3, 1, 1, 4, 3],
    maxCount = 0,
    maxValues;

array.reduce(function (j, a, i, aa) {
    if (aa[j] === a) {
        return j;
    }
    if (i - j === maxCount){
        maxValues.push(aa[j]);
    }            
    if (i - j > maxCount) {
        maxCount = i - j;
        maxValues = [aa[j]];
    }
    return i;
}, -1);

console.log(maxCount);
console.log(maxValues);


0
这是一种实现的方法:
var values = function(obj) {
  var res = [];
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
      res.push(obj[i]);
    }
  }
  return res;
};

var countStreak = function(xs) {
  var res = xs.reduce(function(acc, x, i) {
    if (x === xs[i+1]) {
      acc[x] = acc[x]+1 || 2;
    } else {
      acc[x] = acc[x]-1 || 0;
    }
    return acc;
  },{})
  return Math.max.apply(0, values(res));
};

var ns = [2,5,3,1,1,1,3,7,9,6,4,1,1,1,1,1,4,7,2,3,1,1,4,3]
countStreak(ns) //=> 5

0

我的建议:

function getLongestRow(inputArray) {
    // Initialize dummy variables
    var start = inputArray[0], curRowLen = 0, maxRowLen = 0, maxRowEle = 0;

    // Run through the array
    for(var i = 0;i < inputArray.length;i++) {
        // If current Element does not belong to current row
        if(inputArray[i] != start) {
            // If current row is longer than previous rows, save as new longest row
            if(curRowLen > maxRowLen) {
                maxRowLen = curRowLen;
                maxRowEle = start;
                curRowLen = 1;
            }
            // Start new row
            start = inputArray[i];
        } else {
            // Current element does belongt to current row, increase length
            curRowLen++;
        }
    }

    // Check whether last row was longer than previous rows
    if(curRowLen > maxRowLen) {
        maxRowLen = curRowLen;
        maxRowEle = start;
    }

    // Return longest row & element longest row consits of
    console.log('The longest row in your array consists of '+maxRowLen+' elements of '+maxRowEle+'.');
}

JsFiddle: http://jsfiddle.net/hdwp5/

JsFiddle:http://jsfiddle.net/hdwp5/


0

你可以通过预先查看给定索引处的所有匹配项并跳转到下一个非匹配项的索引来使用更少的迭代。

当剩余的项数少于您找到的最大值时,您也可以退出。

function maxRepeats(arr){
    var L= arr.length, i= 0, 
    max= 1, count= 0;
    while(L-i > max){
        while(arr[i+count]=== arr[i])++count;
        if(count > max) max= count;
        i+= count;
        count= 0;
    }
    return max;
}
var A= [2, 5, 3, 1, 1, 1, 3, 7, 9, 6, 4, 1, 
1, 1, 1, 1, 4, 7, 2, 3, 1, 1, 4, 3];

maxRepeats(A); 返回 5

找到重复最多次数的多个项目并不容易,因为您必须先找到最大数量,然后才能列出它们。 如果您只需要最大数量,请忽略此内容:

function mostRepeats(arr, maximum){
    var i= 0, max= maximum || 1, 
    L= arr.length-max, 
    count= 0, index= [];
    while(i<L){
        while(arr[i+count]=== arr[i])++count;
        if(count=== maximum) index.push(arr[i]+' starting at #'+i);
        else if(count > max) max= count;
        i+= count;
        count= 0;
    }
    if(max===1) return 'No repeats';
    return maximum? max+' repeats of: '+index.join(', '): mostRepeats(arr, max);
}

var A= [2, 5, 3, 1, 1, 1, 3, 7, 9, 6, 4, 1, 1, 1, 
1, 1, 4, 7, 2, 3, 3, 3, 3, 3, 1, 1, 4, 3];

mostRepeats(A);返回:

1的重复出现次数为5,分别从#11和#19开始


0

很遗憾由于声望不足我还不能发表评论,所以我会将这个作为回答来发布。对于我的任务,Robbie Averill的解决方案是完美的,但它包含一个小缺陷。我有一个由两个值-0和1.5组成的数组,但上述代码仅计算了“1.5”值,尽管我有“0”在更高的连续中重复出现。问题在于该值在此处没有做严格的比较:

if(temp != '' && temp == arr[i]) {

修复很简单:if(temp !== '' && temp == arr[i]) {

我已经使用这个修复更新了Robbie的jsfiddler:http://jsfiddle.net/d5X2k/5/


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