如何在多维数组中找到彼此相邻的相同值?

时间:2019-06-01 20:43:21

标签: javascript multidimensional-array

我试图编写一个函数,该函数将在多维数组(值从3到7)中找到,将值重复至少3次(垂直和水平)。如果找到了,请将其更改为其他值。假设1。

我尝试通过循环执行此操作,但这似乎不是解决该问题的好方法,否则我将其弄乱了。因为对于某些数组,它起作用,对于某些数组,它不起作用。

这是我的代码:

function searching(array) {
  for (i = 0; i < array.length; i++) {
    let horizontal = array[i][0];
    let howMany = 1;

    for (j = 1; j < array[i].length; j++) {
      if (horizontal === array[i][j]) {
        howMany += 1;
        horizontal = array[i][j];
        if (howMany >= 3) {
          for (d = j; d > j - howMany; d--) {
            array[i][d] = 0;
          }
        }
      } else {
        horizontal = array[i][j];
        howMany = 1;
      }

    }

  }


  for (v = 0; v < array.length; v++) {
    let vertical = array[0][v];
    let howMany = 1;
    for (x = 1; x < array.length; x++) {
      if (vertical === array[x][v]) {
        howMany++;
        vertical = array[x][v];
        if (howMany >= 3) {
          for (d = x; d > x - howMany; d--) {
            array[d][v] = 0;
          }
        }
      } else {
        vertical = array[x][v];
        howMany = 1;
      }
    }
  }
}

这个想法是例如给数组:

let array = [
    [3, 4, 5, 6, 7],
    [3, 4, 5, 6, 7],
    [3, 4, 5, 5, 5],
    [3, 5, 6, 7, 4]
  ]

结果应该是:

let result = [
    [1, 1, 1, 6, 7],
    [1, 1, 1, 6, 7],
    [1, 1, 1, 1, 1],
    [1, 5, 6, 7, 4]
  ]

在此先感谢您解决问题的任何想法:)问候!

2 个答案:

答案 0 :(得分:0)

我一开始不明白这个问题... 这是我的代码:

let array = [
  [3, 4, 5, 6, 7],
  [3, 4, 5, 6, 7],
  [3, 4, 5, 5, 5],
  [3, 5, 6, 7, 4]
];

function replace(arr, target = 1) {
  let needToChange = []; // save the index to change
  const numbers = [3, 4, 5, 6, 7];
  const m = arr.length; // m rows
  const n = arr[0].length; // n columns

  let mi = 0;
  let ni = 0;

  // search in row
  for (mi = 0; mi < m; mi++) {
    for (let x = 0; x < numbers.length; x++) {
      const num = numbers[x]; // number to search
      let counter = 0; // counter for this number in row mi
      let tempArr = [];
      for (ni = 0; ni < n; ni++) {
        const currentNum = arr[mi][ni];
        if (currentNum === num) {
          counter++;
          tempArr.push([mi, ni]);
        }
      }
      if (counter >= 3) {
        needToChange = needToChange.concat(tempArr);
      }
    }
  }

  // search in column
  for (ni = 0; ni < n; ni++) {
    for (let x = 0; x < numbers.length; x++) {
      const num = numbers[x]; // number to search
      let counter = 0; // counter for this number in row mi
      let tempArr = [];
      for (mi = 0; mi < m; mi++) {
        const currentNum = arr[mi][ni];
        if (currentNum === num) {
          counter++;
          tempArr.push([mi, ni]);
        }
      }
      if (counter >= 3) {
        needToChange = needToChange.concat(tempArr);
      }
    }
  }

  // replace
  needToChange.forEach(([i, j]) => {
    array[i][j] = target;
  });
}

replace(array);
array.forEach(row => {
  console.log(row.join(', '));
})

答案 1 :(得分:0)

您当前代码的问题是

(1)您仅检查单个行和列,当您需要同时检查它们时(例如,使用[[2, 2], [2, 5]],当在起始位置[0][0]时,您需要查看[0][1](如果匹配,还包括其邻居)以及[1][0](如果匹配,则及其邻居)。

(2)目前,您实际上并没有检查邻接关系,只是在计算特定行或列中匹配元素的总数。

遍历数组的所有索引。如果已经检查了索引,请尽早返回。递归搜索该索引的邻居,如果总共找到至少3个匹配项,请将它们全部设置为1。将所有匹配的邻居放入checked集中,以避免再次检查它们(即使少于2个)总共找到了相邻的匹配项。

setAllAdjacentToOne([
  [3, 4, 5, 6, 7],
  [3, 4, 5, 6, 7],
  [3, 4, 5, 5, 5],
  [3, 5, 6, 7, 4]
]);
// all 9s stay, the rest get set to 1:
setAllAdjacentToOne([
  [2, 2, 9, 7, 7],
  [2, 9, 9, 9, 7],
  [3, 4, 4, 5, 5],
  [9, 4, 5, 5, 9]
]);


function setAllAdjacentToOne(input) {
  const output = input.map(subarr => subarr.slice());
  const checked = new Set();
  const getKey = (x, y) => `${x}_${y}`;

  const width = input[0].length;
  const height = input.length;
  const getAllAdjacent = (x, y, numToFind, matches = []) => {
    if (x >= width || x < 0 || y >= height || y < 0) {
      return matches;
    }
    const key = getKey(x, y);
    if (!checked.has(key) && input[y][x] === numToFind) {
      checked.add(key);
      matches.push({ x, y });
      getAllAdjacent(x + 1, y, numToFind, matches);
      getAllAdjacent(x - 1, y, numToFind, matches);
      getAllAdjacent(x, y + 1, numToFind, matches);
      getAllAdjacent(x, y - 1, numToFind, matches);
    }
    return matches;
  };

  output.forEach((innerRowArr, y) => {
    innerRowArr.forEach((num, x) => {
      const allAdjacent = getAllAdjacent(x, y, num);
      if (allAdjacent.length <= 2) {
        return;
      }
      allAdjacent.forEach(({ x, y }) => {
        output[y][x] = 1;
      });
    });
  });
  console.log(JSON.stringify(output));
}