当谈到矩阵遍历和任何类型的搜索时,我发现我经常需要验证一个潜在的项目,以便添加到我的队列或递归。
说我们正在看这个矩阵:
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])
}
}
答案 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));