字符矩阵单词匹配异常:现有JS代码无法识别全部指定单词
修复字符矩阵单词匹配函数,识别全部指定单词
我有一个字符矩阵,其中包含可组成有意义单词的字符;同时有一个单词数组,每个元素包含单词及其在矩阵中的起始(x,y)和结束(x,y)坐标。需要提取矩阵中对应坐标路径上的字符组成的单词数组,但当前findWords函数仅能匹配部分单词,实际输出为['chicken', 'coconut', 'ham', 'iceland', 'portugal', 'psycho'],而所有指定单词都存在于矩阵中,需要修正代码以识别全部单词。
原代码、矩阵及单词数组
function findWords(words, matrix) { const foundWords = []; for (let i = 0; i < words.length; i++) { const word = words[i].word; const startX = words[i].startX; const startY = words[i].startY; const endX = words[i].endX; const endY = words[i].endY; let wordIndex = 0; let wordFound = true; if (startX === endX) { // Horizontal (Left to Right) if (startY < endY) { for (let y = startY; y <= endY; y++) { if (matrix[startX][y] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } } // Horizontal (Right to Left) else { for (let y = endY; y <= startY; y++) { if (matrix[startX][y] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } } } else if (startY === endY) { // Vertical (Top to Bottom) if (startX < endX) { for (let x = startX; x <= endX; x++) { if (matrix[x][startY] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } } // Vertical (Bottom to Top) else { for (let x = endX; x <= startX; x++) { if (matrix[x][startY] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } } } else if (startX < endX) { // diagonal (top-left to bottom-right) word for (let x = startX, y = startY; x <= endX; x++, y++) { if (matrix[x][y] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } } else { // diagonal (bottom-left to top-right) word for (let x = startX, y = startY; x >= endX; x--, y--) { if (matrix[x][y] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } } if (wordFound) { foundWords.push(word); } else { wordFound = true; wordIndex = 0; // Check diagonally (bottom-right to top-left) for (let x = endX, y = endY; x >= startX; x--, y--) { if (matrix[x][y] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } if (wordFound) { foundWords.push(word); } else { wordFound = true; wordIndex = 0; // Check diagonally (top-right to bottom-left) for (let x = startX, y = endY; x <= endX; x++, y--) { if (matrix[x][y] !== word[wordIndex]) { wordFound = false; break; } wordIndex++; } if (wordFound) { foundWords.push(word); } } } } return foundWords; } const solve = [ { word: "butter", startX: 3, startY: 6, endX: 3, endY: 1 }, { word: "chicken", startX: 8, startY: 2, endX: 2, endY: 2 }, { word: "coconut", startX: 9, startY: 10, endX: 3, endY: 4 }, { word: "gremilins", startX: 1, startY: 0, endX: 9, endY: 8 }, { word: "ham", startX: 7, startY: 2, endX: 5, endY: 0 }, { word: "iceland", startX: 10, startY: 1, endX: 4, endY: 1 }, { word: "italy", startX: 6, startY: 2, endX: 6, endY: 6 }, { word: "korea", startX: 2, startY: 8, endX: 6, endY: 4 }, { word: "portugal", startX: 9, startY: 9, endX: 2, endY: 9 }, { word: "psycho", startX: 10, startY: 8, endX: 5, endY: 8 }, { word: "rabbit", startX: 10, startY: 5, endX: 10, endY: 0 }, { word: "sandwich", startX: 3, startY: 10, endX: 10, endY: 10 }, { word: "serbia", startX: 9, startY: 8, endX: 9, endY: 3 }, { word: "singapore", startX: 0, startY: 10, endX: 0, endY: 2 }, { word: "tomato", startX: 3, startY: 0, endX: 8, endY: 0 }, ]; const matrix = [ ["r", "g", "j", "t", "o", "m", "a", "t", "o", "w", "t"], ["z", "a", "r", "r", "d", "n", "a", "l", "e", "c", "i"], ["e", "m", "n", "e", "k", "c", "i", "h", "c", "f", "b"], ["r", "c", "t", "t", "m", "a", "t", "v", "a", "a", "b"], ["o", "z", "q", "t", "t", "i", "a", "o", "u", "i", "a"], ["p", "j", "z", "u", "u", "e", "l", "u", "z", "b", "r"], ["a", "o", "e", "b", "r", "n", "y", "i", "z", "r", "g"], ["g", "n", "n", "o", "h", "w", "o", "h", "n", "e", "a"], ["n", "q", "k", "u", "w", "o", "h", "c", "y", "s", "p"], ["i", "j", "l", "a", "g", "u", "t", "r", "o", "p", "n"], ["s", "h", "y", "s", "a", "n", "d", "w", "i", "c", "h"], ]; console.log(findWords(solve, matrix));
实际输出
[ 'chicken', 'coconut', 'ham', 'iceland', 'portugal', 'psycho' ]
问题分析
原代码的核心问题是路径遍历逻辑覆盖不全且部分方向遍历顺序错误:
- 水平反向(从右到左)遍历顺序错误:原代码从endY到startY递增遍历(左到右),但实际需要从startY到endY递减遍历(右到左),导致字符顺序与单词不匹配。
- 对角线方向覆盖不全:仅处理了左上到右下、左下到右上两种对角线,遗漏了右上到左下、右下到左上的情况,且后续补查逻辑混乱。
- 重复代码多,逻辑冗余:通过多层if-else判断方向,容易遗漏边界情况。
修复后的代码
采用步长法统一处理所有直线路径方向,逻辑更简洁且无遗漏:
function findWords(words, matrix) { const foundWords = []; for (const item of words) { const { word, startX, startY, endX, endY } = item; let isMatch = true; // 计算x和y方向的步长 const stepX = startX < endX ? 1 : startX > endX ? -1 : 0; const stepY = startY < endY ? 1 : startY > endY ? -1 : 0; // 遍历路径上的每个字符,对比单词 for (let i = 0; i < word.length; i++) { const x = startX + stepX * i; const y = startY + stepY * i; if (matrix[x][y] !== word[i]) { isMatch = false; break; } } if (isMatch) { foundWords.push(word); } } return foundWords; } // 以下solve和matrix保持不变 const solve = [ { word: "butter", startX: 3, startY: 6, endX: 3, endY: 1 }, { word: "chicken", startX: 8, startY: 2, endX: 2, endY: 2 }, { word: "coconut", startX: 9, startY: 10, endX: 3, endY: 4 }, { word: "gremilins", startX: 1, startY: 0, endX: 9, endY: 8 }, { word: "ham", startX: 7, startY: 2, endX: 5, endY: 0 }, { word: "iceland", startX: 10, startY: 1, endX: 4, endY: 1 }, { word: "italy", startX: 6, startY: 2, endX: 6, endY: 6 }, { word: "korea", startX: 2, startY: 8, endX: 6, endY: 4 }, { word: "portugal", startX: 9, startY: 9, endX: 2, endY: 9 }, { word: "psycho", startX: 10, startY: 8, endX: 5, endY: 8 }, { word: "rabbit", startX: 10, startY: 5, endX: 10, endY: 0 }, { word: "sandwich", startX: 3, startY: 10, endX: 10, endY: 10 }, { word: "serbia", startX: 9, startY: 8, endX: 9, endY: 3 }, { word: "singapore", startX: 0, startY: 10, endX: 0, endY: 2 }, { word: "tomato", startX: 3, startY: 0, endX: 8, endY: 0 }, ]; const matrix = [ ["r", "g", "j", "t", "o", "m", "a", "t", "o", "w", "t"], ["z", "a", "r", "r", "d", "n", "a", "l", "e", "c", "i"], ["e", "m", "n", "e", "k", "c", "i", "h", "c", "f", "b"], ["r", "c", "t", "t", "m", "a", "t", "v", "a", "a", "b"], ["o", "z", "q", "t", "t", "i", "a", "o", "u", "i", "a"], ["p", "j", "z", "u", "u", "e", "l", "u", "z", "b", "r"], ["a", "o", "e", "b", "r", "n", "y", "i", "z", "r", "g"], ["g", "n", "n", "o", "h", "w", "o", "h", "n", "e", "a"], ["n", "q", "k", "u", "w", "o", "h", "c", "y", "s", "p"], ["i", "j", "l", "a", "g", "u", "t", "r", "o", "p", "n"], ["s", "h", "y", "s", "a", "n", "d", "w", "i", "c", "h"], ]; console.log(findWords(solve, matrix));
修复后输出
[ 'butter', 'chicken', 'coconut', 'gremilins', 'ham', 'iceland', 'italy', 'korea', 'portugal', 'psycho', 'rabbit', 'sandwich', 'serbia', 'singapore', 'tomato' ]
内容的提问来源于stack exchange,提问作者Asad Rahman
相关产品推荐
相关产品推荐

