JavaScript沟渠导航程序T型分支检测失效及代码报错求助
沟渠导航程序问题修复
核心问题分析与修复步骤
1. 解决current is not iterable错误
这个错误根源是Set存储数组的引用问题:JavaScript里数组属于引用类型,Set判断元素是否相等时,对比的是对象引用而非值。比如你执行visited.add([2,1])后,再用visited.has([2,1])会返回false——因为这两个是完全独立的数组对象。这种逻辑混乱会导致重复压栈、非数组的current值等问题。
修复方法:把坐标转成"行,列"格式的字符串存入Set,所有涉及visited的操作都改用字符串判断:
- 示例:
visited.add(${row},${col}),判断时用visited.has(${neighbor[0]},${neighbor[1]})。
2. 修复T型分支检测逻辑
原代码的T型检测逻辑完全错误,有效沟渠是线性结构,每个节点最多只能有2个相邻的沟渠节点;如果某个节点的沟渠邻居数≥3,就属于T型分支,直接判定为无效。
修复方法:遍历每个节点时,检查其有效邻居数量:
const neighbors = findNeighbors(current, matrix); if (neighbors.length > 2) { // 存在3个及以上沟渠邻居,属于T型分支,返回false isValid = false; break; }
注意:原代码用forEach里的return false只会终止当前循环,无法终止整个函数,改用for循环或标志位才能正确中断遍历。
3. 修复identifyTrench的循环逻辑
原代码只要遇到第一个无效的沟渠节点就直接返回false,忽略了后续可能存在的有效沟渠。正确逻辑是:只有找到有效沟渠时才返回true,否则继续遍历所有节点。
修复方法:去掉else分支的直接返回,仅在检测到有效沟渠时返回true:
if (trenchMatrix[i][j] < -5) { if (trenchTraversal([i, j], trenchMatrix, visited)) { return true; } // 不直接返回false,继续循环查找其他节点 }
4. 修复提前返回导致的检测不完整
原代码中if (pathArr.length >= 3) return true;放在循环每次迭代末尾,会导致路径长度刚到3就立刻返回,无法完成全遍历,也就没法检测后续是否存在T型分支。正确做法是:等整个遍历完成后,再判断是否满足“无T型分支+路径长度≥3”的条件。
修改后的完整代码
// 查找邻居节点 function findNeighbors(node, matrix) { const res = []; const row = node[0]; const col = node[1]; // 北 if (row > 0) { const nVal = matrix[row - 1][col]; if (nVal < -5) res.push([row - 1, col]); } // 南 if (row < matrix.length - 1) { const sVal = matrix[row + 1][col]; if (sVal < -5) res.push([row + 1, col]); } // 东 if (col < matrix[0].length - 1) { const eVal = matrix[row][col + 1]; if (eVal < -5) res.push([row, col + 1]); } // 西 if (col > 0) { const wVal = matrix[row][col - 1]; if (wVal < -5) res.push([row, col - 1]); } return res; }; // 遍历沟渠并检测有效性 function trenchTraversal(node, matrix, visited) { const [row, col] = node; if (matrix[row][col] >= -5) return false; const stack = [node]; const currentPath = new Set(); // 记录当前遍历的沟渠节点 currentPath.add(`${row},${col}`); visited.add(`${row},${col}`); let isValid = true; while (stack.length && isValid) { const current = stack.pop(); const [currentRow, currentCol] = current; const neighbors = findNeighbors(current, matrix); // 检测T型分支:当前节点有超过2个沟渠邻居 if (neighbors.length > 2) { isValid = false; break; } // 遍历邻居,加入栈中 for (const neighbor of neighbors) { const neighborKey = `${neighbor[0]},${neighbor[1]}`; if (!currentPath.has(neighborKey)) { currentPath.add(neighborKey); visited.add(neighborKey); stack.push(neighbor); } } } // 有效沟渠条件:无T型分支,且节点数≥3 return isValid && currentPath.size >= 3; }; // 识别矩阵中是否存在有效沟渠 function identifyTrench(trenchMatrix) { const visited = new Set(); for (let i = 0; i < trenchMatrix.length; i++) { for (let j = 0; j < trenchMatrix[0].length; j++) { const key = `${i},${j}`; if (trenchMatrix[i][j] < -5 && !visited.has(key)) { if (trenchTraversal([i, j], trenchMatrix, visited)) { return true; } } } } return false; }; // 本地测试 const sonar_0 = [ [-5, -5, -5], [-6, -5, -8], [-5, -7, -5] ] console.log(findNeighbors([1,1], sonar_0)); // 预期输出: [[2, 1], [1, 0], [1, 2]] const test_visited = new Set(); test_visited.add("2,1"); console.log(trenchTraversal([0, 1], sonar_0, test_visited)); const sonar_1 = [ [-5,-5,-5,-5,-5], [-5,-8,-8,-9,-7], [-5,-5,-5,-5,-8], [-5,-5,-5,-5,-5] ]; console.log(identifyTrench(sonar_1)) // 预期输出: true const sonar_2 = [ [-5,-5,-5,-7,-5], [-5,-8,-8,-9,-5], [-5,-5,-5,-7,-5], [-5,-5,-5,-5,-5] ]; console.log(identifyTrench(sonar_2)) // 预期输出: false const sonar_3 = [ [-5,-5,-5,-5,-5], [-5,-5,-5,-5,-5], [-5,-9,-9,-5,-5], [-5,-5,-5,-5,-5] ]; console.log(identifyTrench(sonar_3)) // 预期输出: false
内容的提问来源于stack exchange,提问作者Boo Shorty
相关产品推荐
相关产品推荐

