如何在javascript中识别数组中的重复模式

时间:2018-01-04 11:35:21

标签: javascript algorithm

如果我有像

这样的数组

const arr = [1, 5, 7, 5, 13, 8, 1, 7, 3, 8, 5, 2, 1, 5, 7];

找到数组开始重复的最佳方法是什么?在这种情况下,前三个数字和后三个数字是重复模式。

这是一个随机数组,重复很容易从索引365开始,而不一定是从第一个索引开始。

有什么想法吗?

提前致谢

3 个答案:

答案 0 :(得分:1)

这就是你正在寻找的......



const arr1 = [1, 5, 7, 5, 13, 8, 1, 7, 3, 8, 5, 2, 1, 5, 7];
const arr2 = [1, 5, 7, 5, 13, 8, 1, 7, 3, 8, 5, 2, 1, 4, 7];

function patternFound(arr) {
  var newArray = arr.map(function(o, i) {
      if (i < arr.length - 1) {
        return arr[i] + "|" + arr[i + 1];
      }
    })
    .sort();

  newArray = newArray.filter(function(o, i) {
      if (i < arr.length - 1) {
      	return (o == newArray[i + 1]);
      }
    });

  return newArray.length > 0;
}

console.log(patternFound(arr1));
console.log(patternFound(arr2));
&#13;
&#13;
&#13;

基本上,它从第一个数组创建一个配对元素数组,并使用管道分隔符(["1|5", "5|7", "7|5" etc.])对其进行排序,然后通过将每个元素与下一个元素进行比较来查找重复项。

可能这样做的方式要小得多,但我并不想花时间制作一些不可读的东西。这可以满足您的需求,并且操作简单明了。

第一个数组是您提供的数组,第二个数组已更改,因此没有匹配的模式。

答案 1 :(得分:0)

嵌套循环似乎是最简单的方法。

确保偏移嵌套循环以保存计算:

/**
 * Takes array and returns either boolean FALSE or the first index of a pattern
 *
 * @param {any[]} arr
 * @returns {(false | number)}
 */
function findArrayPattern(arr) {
  if (arr.length < 2) {
    return false;
  }
  for (var point1 = 0; point1 < arr.length - 2; point1++) {
    var p1 = arr[point1];
    var p2 = arr[point1 + 1];
    for (var point2 = point1 + 2; point2 < arr.length - 1; point2++) {
      var p3 = arr[point2];
      var p4 = arr[point2 + 1];
      if (p1 == p3 && p2 == p4) {
        return point1;
      }
    }
  }
  return false;
}
//TEST
var arr = [1, 5, 7, 5, 13, 8, 1, 7, 3, 8, 5, 2, 1, 5, 7];
var pattern = findArrayPattern(arr);
if (pattern !== false) {
  console.log("a pattern was found at " + pattern);
} else {
  console.log("no pattern was found");
}

答案 2 :(得分:0)

您可以使用带有短路的单循环方法和用于找到对的哈希表,例如

{
    "1|5": true,
    "5|7": true,
    "7|5": true,
    "5|13": true,
    "13|8": true,
    "8|1": true,
    "1|7": true,
    "7|3": true,
    "3|8": true,
    "8|5": true,
    "5|2": true,
    "2|1": true
}

迭代在索引12上立即停止,其他找到的对1|5

&#13;
&#13;
function check(array) {
    var hash = Object.create(null);
    return array.some(function (v, i, a) {
        var pair = [v, a[i + 1]].join('|');
        return hash[pair] || !(hash[pair] = true);
    });
}

console.log(check([1, 5, 7, 5, 13, 8, 1, 7, 3, 8, 5, 2, 1, 5, 7])); //  true
console.log(check([1, 5, 7, 5, 13, 8, 1, 7, 3, 8, 5, 2, 1, 3, 7])); // false
&#13;
&#13;
&#13;