【问题标题】:how to check empty value in multidensional array in this box如何在此框中检查多维数组中的空值
【发布时间】:2019-07-29 11:18:25
【问题描述】:

你好,我想知道找到 3x3 框周围空值的算法

像这样的示例多维数组

[
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ]

我只想得到 3x3 的盒子,所以盒子里面的空值我可以填充我想要的任何东西,如何解决/验证这种情况? 所以结果是得到那个空值INDEX

我正在尝试这个:

for (let i = 0; i < array.length; i++) {
    for (let j = 0; j < array[i].length; j++) {
      if(array[i]){
        if(array[i][j] == '#' &&
           array[i+1][j] == '#' && 
           array[i+2][j] == '#' &&
           array[i][j+1] == '#' && 
           array[i][j+2] == '#' &&
           array[i+2][j+2]

         ){
           console.log(i);
         }
      }

    }
  }

【问题讨论】:

  • 你尝试了什么?
  • 试过可以分享代码吗
  • 检查那里:D,
  • 在这里stackoverflow.com/questions/2478447/…你可以找到类似的东西,但是寻找一个“实心”的盒子,也许你可以从那里开始?
  • 另外,盒子应该总是 3x3 吗?

标签: javascript loops for-loop matrix multidimensional-array


【解决方案1】:

您可以搜索每行中的第一个###,因为它是顶部边框。然后,一旦你找到它,验证盒子的其余部分是否存在。如果是这样,您已经找到了第一个 3x3 框:

var arr = [
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "],
    [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
    [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
    [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
  ];
  
for (let i = 0; i < arr.length; i++) {

  //convert row to string
  let row = arr[i].join("");
  
  //search for top border
  if (row.indexOf("###") != -1) {
    
    let ind = row.indexOf("###");

    //verify box
    if (arr[i+1][ind] == "#" && arr[i+1][ind+2] == "#" && arr[i+2].join("").substr(ind,3) == "###") {
      console.log("Found at: " + i + ", " + ind);
      break;
    }
  }
}

【讨论】:

    【解决方案2】:

    1) 您的方框是 3x3 = 9 个要检查的单元格。您只检查了其中的六个。

    2) 您正在检查 index + 2 从左上角到右下角,这意味着您应该在 length - 2 处停止循环。

    3) 您基本上需要处理该 3x3 区域中的每个单元格。

    Here's how you do that:

    for (let i = 0; i < array.length - 2; i++) {
        for (let j = 0; j < array[i].length - 2; j++) {
            if (
                // first row
                array[i][j] == '#'
                && array[i][j + 1] == '#'
                && array[i][j + 2] == '#'
    
                // second row
                && array[i + 1][j] == '#'
                && array[i + 1][j + 1] == ' '
                && array[i + 1][j + 2] == '#'
    
                // third row
                && array[i + 2][j] == '#'
                && array[i + 2][j + 1] == '#'
                && array[i + 2][j + 2] == '#'
             ) {
                console.log('box upper-left corner is: ' + i + ' x ' + j + '<br />');
             }
    
        }
    }
    

    如果您正在寻找框中“emtpy”单元格的地址,那么您正在寻找i + 1j + 1

    【讨论】:

    • 我试过了,但是I和J必须再次加+1才能得到答案
    【解决方案3】:

    您在正确的轨道上,这是您的版本,稍作更改和添加:

    array = [
      [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
      [" ", " ", "#", "find me", "#", " ", " ", " ", " ", " "],
      [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
      [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
      [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
      [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
      [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
      [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
      [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
    ]
    
    for (let i = 0; i < array.length-2; i++) {
      for (let j = 0; j < array[i].length-2; j++) {
        if(array[i][j] == '#' &&
        array[i+1][j] == '#' && 
        array[i+2][j] == '#' &&
        array[i][j+1] == '#' && 
        array[i][j+2] == '#' &&
        array[i+1][j+2] == '#' &&
        array[i+2][j+1] == '#' &&
        array[i+2][j+2] == '#'){
          console.log(array[i+1][j+1]);
        }
      }
    }

    【讨论】:

      【解决方案4】:

      我首先为我们的 check 函数创建了两个正面测试用例 -

      const puzzle1 =
        [ [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
        , [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "]
        , [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        ]
      
      const puzzle2 =
        [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", " ", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        ]
      
      console.log(check(puzzle1))
      // expected: [ 0, 2 ]
      
      console.log(check(puzzle2))
      // expected: [ 3, 4 ]
      

      还有一个否定的情况-

      const puzzle3 =
        [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        ]
      
      console.log(check(puzzle3))
      // expected: false
      

      首先我实现了crossblank 来更轻松地处理子问题-

      const cross = x =>
        x === "#"
      
      const blank = x =>
        x === " "
      

      现在我们实现check -

      const check = 
        ( [ [ a, b, c, ...r0 ] = []
          , [ d, e, f, ...r1 ] = []
          , [ g, h, i, ...r2 ] = []
          , ...rest
          ]
        , row = 0
        , col = 0
        ) =>
      
        // bottom-right is out of bounds
        i === undefined
          ? false
      
        // perimeter is cross and center is blank
        // solution found: return the row and col
        : [ a, b, c, d, f, g, h, i ] .every (cross) && blank (e)
          ? [ row, col ]
      
        // otherwise check the next column
        : check
            ( [ [ b, c, ...r0 ]
              , [ e, f, ...r1 ]
              , [ h, i, ...r2 ]
              , ...rest .map (([ _, ...row ]) => row)
              ]
            , row
            , col + 1
            )
          || // or check the next row
          check
            ( [ [ d, e, f, ...r1 ]
              , [ g, h, i, ...r2 ]
              , ...rest
              ]
            , row + 1
            , col
            )
      

      我喜欢这个解决方案,因为我们可以直观地看到检查中发生了什么 -

      // (a b c f i h g d) makes a "donut" shape
      // (e) is the donut hole
      [ [ a, b, c, ...r0 ] = []
      , [ d, e, f, ...r1 ] = []
      , [ g, h, i, ...r2 ] = []
      , ...rest
      ]
      
      // how am I supposed to visualize this?
      arr[row][col] == "#"
      arr[row+1][col] == "#"
      arr[row+2][col] == "#"
      arr[row][col+1] == "#"
      arr[row+1][col+1] == " "
      arr[row+2][col+1] == "#"
      arr[row][col+2] == "#"
      arr[row+1][col+2] == "#"
      arr[row+2][col+2] == "#"
      

      使用嵌套的for 循环会限制我们使用索引来思考问题并执行手动查找,例如arr[row+1][col+2]。在这种粒度级别上思考会使大脑感到疲劳,并且容易产生错误的程序。相比之下,深度解构和递归的使用使我们的程序能够反映其数据的形状并将我们从复杂性中解放出来。

      展开下面的程序,在你自己的浏览器中验证结果-

      const cross = x =>
        x === "#"
        
      const blank = x =>
        x === " "
      
      const check = 
        ( [ [ a, b, c, ...r0 ] = []
          , [ d, e, f, ...r1 ] = []
          , [ g, h, i, ...r2 ] = []
          , ...rest
          ]
        , row = 0
        , col = 0
        ) =>
        i === undefined
          ? false
        : [ a, b, c, d, f, g, h, i ] .every (cross) && blank(e)
          ? [ row, col ]
        : check
            ( [ [ b, c, ...r0 ]
              , [ e, f, ...r1 ]
              , [ h, i, ...r2 ]
              , ...rest .map (([ _, ...row ]) => row)
              ]
            , row
            , col + 1
            )
          ||
          check
            ( [ [ d, e, f, ...r1 ]
              , [ g, h, i, ...r2 ]
              , ...rest
              ]
            , row + 1
            , col
            )
      
      const puzzle1 =
        [ [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
        , [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "]
        , [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        ]
      
      const puzzle2 =
        [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", " ", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        ]
      
      const puzzle3 =
        [ [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", "#", "#", "#", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        , [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
        ]
      
      console.log(check(puzzle1))
      // [ 0, 2 ]
      
      console.log(check(puzzle2))
      // [ 3, 4 ]
      
      console.log(check(puzzle3))
      // false

      【讨论】:

      • 我试图理解你的方法,我仍然感到困惑,我喜欢你的 wtite 代码,
      • 你能告诉我检查参数的内部吗?以及每种方法之后的黑色(e)是什么。是否也包括空白(e)上的每个方法??
      • 您好 Zum Dummi,感谢您的评论,抱歉回复晚了。 blank 在前面的答案中定义;它只是检查一个字符是否是一个空格," "check 参数正在使用destructuring assignment;你有没有被困在某个特定的领域?
      【解决方案5】:

      这是一种面向对象的方法:

      class Cell {
        constructor(coordinates, content) {
          this.coordinates = coordinates;
          this.content = content;
        }
      
        get allNeighbours() {
          return Cell
            .neighbourDirections
            .map(direction => this[direction]);
        }
      
        get neighbours() { // unused
          return this.allNeighbours
            .filter(neighbour => neighbour);
        }
      
        get isBoxCentre() {
          return this.content === ' ' &&
            this.allNeighbours
              .every(neighbour => neighbour && neighbour.content === '#');
        }
      }
      
      Cell.relativeNeighbourDirections = {
        north: [0, 1],  northEast: [1, 1], 
        east:  [1, 0],  southEast: [1, -1],
        south: [0, -1], southWest: [-1, -1], 
        west:  [-1, 0], northWest: [-1, 1]
      };
      
      Cell.neighbourDirections = Object.keys(Cell.relativeNeighbourDirections);
      
      
      class Grid {
        constructor(gridArray) {
          this.cells = [];
      
          // instantiate cells
          this.gridArray = gridArray.map((row, x) => {
            return row.map((content, y) => {
              let cell = new Cell([x, y], content);
              this.cells.push(cell);
              return cell;
            });
          });
          
          this._assignNeighbours();
        }
      
        // returns an array with the coordinates of all box centres
        get boxCoordinates() {
          return this.cells
            .filter(cell => cell.isBoxCentre)
            .map(cell => cell.coordinates);
        }
      
        _assignNeighbours() {
          this.gridArray.forEach((row, x) => {
            row.forEach((cell, y) => {
              Cell.neighbourDirections.forEach(direction => {
                let [relX, relY] = Cell.relativeNeighbourDirections[direction];
      
                let neighbourX = x + relX,
                    neighbourY = y + relY;
      
                // x and y must be in bounds
                if (
                  neighbourX < 0 ||
                  neighbourX >= this.gridArray.length ||
                  neighbourY < 0 ||
                  neighbourY >= row.length
                ) return;
      
                cell[direction] = this.gridArray[neighbourX][neighbourY];
              });
            });
          });
        }
      }
      
      
      let grid = new Grid([
          [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
          [" ", " ", "#", " ", "#", " ", " ", " ", " ", " "],
          [" ", " ", "#", "#", "#", " ", " ", " ", " ", " "],
          [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
          [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
          [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
          [" ", " ", " ", " ", " ", " ", " ", " ", "#", " "],
          [" ", " ", " ", " ", " ", " ", " ", " ", "#", "#"],
          [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "]
      ]);
      
      console.log(grid.boxCoordinates);

      有关 JavaScript 类的更多信息,请查看:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-28
        • 1970-01-01
        • 2017-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多