在计算岛屿时检查异常

时间:2016-08-06 17:50:50

标签: javascript algorithm matrix data-structures

当谈到矩阵遍历和任何类型的搜索时,我发现我经常需要验证一个潜在的项目,以便添加到我的队列或递归。

说我们正在看这个矩阵:

var matrixTest = [
      [1,1,0,0,0], 
      [1,1,0,0,0], 
      [0,0,1,0,0], 
      [0,0,0,1,1]
]

在这种情况下,当我遇到1时,我正在迭代所有项目并执行BFS(标记为已访问)。

我的BFS函数中有一个子程序,给定一个坐标r和c,它验证从它导出的所有可能路径(r + 1,r-1,c + 1,c-1)。

问题在于这段代码

if(!visitMap[r+1][c] && matrix[r+1][c] === 1) {
      q.push([r+1, c])
    }

visitMap是我在算法旁边创建的矩阵,以确保我没有处理两次点

矩阵是输入矩阵

但是,我似乎需要在测试之前验证输入,因为JavaScript会抛出此错误

TypeError: Cannot read property '3' of undefined

我认为这意味着我的“r + 1”表达式位于矩阵的边界之外,因此处理为未定义。

添加另一层if / then流来检查r + 1,r-1,c + 1和c-1的界限似乎非常繁琐。

您是否建议使用特定的代码模式以避免多次执行此操作?

否则我认为代码块看起来像这样:

if (r+1 < matrix.length) {

    if(!visitMap[r+1][c] && matrix[r+1][c] === 1) {
         q.push([r+1, c])
      }
  }

2 个答案:

答案 0 :(得分:2)

您可以尝试在这样的函数中封装边界和条件的验证:

function pushToQueue(visitMap, matrix, r, c) { 
    if( typeof(matrix[r]) == "undefined"
        || typeof(matrix[r][c]) == "undefined" )  {
    return false; 
    }
    return !visitMap[r][c] && matrix[r][c] === 1; 
}

你可以这样称呼它:

if(pushToQueue(visitMap, matrix, r + 1, c)) {
   q.push([r+1, c]); 
}

if(pushToQueue(visitMap, matrix, r - 1, c)) {
  q.push([r-1, c]); 
} 
// etc ...

答案 1 :(得分:1)

一种解决方案是每次尝试访问易于超出界限的位置时使用函数。

因此,matrix[r+1][c] === 1将成为readMatrix(c, r+1) === 1

即使在复杂的循环中,这对整体性能的影响也非常小。 (如果最终机器代码中涉及任何分支预测器,它应该在大多数情况下进行正确的猜测,因为大部分时间都在矩阵内。)

var matrix = [
  [1,1,0,0,0], 
  [1,1,0,0,0], 
  [0,0,1,0,0], 
  [0,0,0,1,1]
];

function readMatrix(x, y) {
  return matrix[y] && matrix[y][x] !== undefined ? matrix[y][x] : 0;
}

console.log(readMatrix(0, 0));
console.log(readMatrix(0, 7));
console.log(readMatrix(7, 0));