Java技术求助:如何在char[][]数组中搜索指定字符串?
解决二维字符数组中搜索连续字符串的问题
嘿,我完全懂你现在卡在哪了——你当前的代码只是在逐个确认目标字符串的每个字符是否存在于二维数组中,但完全没处理「连续相邻字符匹配」的核心逻辑,而且k的递增逻辑也完全不对,因为你的循环结构根本没法跟踪上一个匹配字符的位置,自然没法继续匹配下一个字符。
问题根源分析
你的现有代码存在几个关键问题:
- 三层循环的顺序错误:
k在外层循环意味着你会先把整个数组扫一遍找charArray[0],再扫一遍找charArray[1],但完全不关心这两个字符是否相邻 - 找到匹配字符后没有记录位置,也没有逻辑触发去匹配下一个字符
- 没有处理「不能重复使用同一个数组位置」的情况(这类字符串搜索题通常都有这个约束)
解决方案:回溯+递归
因为目标字符串长度不固定,递归+回溯是最适合的方案——每次匹配一个字符后,递归检查它的相邻位置是否匹配下一个字符,同时用一个标记数组记录已访问的位置,避免重复使用。
完整实现代码
public static boolean search(char[][] puzzle, String word) { if (puzzle == null || puzzle.length == 0 || word == null || word.isEmpty()) { return false; } char[] charArray = word.toCharArray(); int rows = puzzle.length; int cols = puzzle[0].length; // 创建访问标记数组,防止重复使用同一个位置的字符 boolean[][] visited = new boolean[rows][cols]; // 遍历二维数组的每个位置,作为匹配的起点 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 如果当前字符匹配目标字符串的第一个字符,开始递归匹配 if (puzzle[i][j] == charArray[0]) { if (backtrack(puzzle, charArray, visited, i, j, 0)) { return true; } } } } return false; } // 回溯递归方法 private static boolean backtrack(char[][] puzzle, char[] target, boolean[][] visited, int i, int j, int currentIndex) { // 终止条件:当前匹配的索引等于目标字符串长度,说明全部匹配成功 if (currentIndex == target.length) { return true; } // 边界检查:越界、当前字符不匹配、已访问过,直接返回false if (i < 0 || i >= puzzle.length || j < 0 || j >= puzzle[0].length || visited[i][j] || puzzle[i][j] != target[currentIndex]) { return false; } // 标记当前位置为已访问 visited[i][j] = true; // 递归检查上下左右四个相邻方向(如果需要支持斜向匹配,就加上另外四个方向:i+1,j+1; i+1,j-1; i-1,j+1; i-1,j-1) boolean found = backtrack(puzzle, target, visited, i + 1, j, currentIndex + 1) || backtrack(puzzle, target, visited, i - 1, j, currentIndex + 1) || backtrack(puzzle, target, visited, i, j + 1, currentIndex + 1) || backtrack(puzzle, target, visited, i, j - 1, currentIndex + 1); // 回溯:恢复当前位置的访问状态,以便其他路径可以使用 visited[i][j] = false; return found; }
代码说明
- 主方法逻辑:
- 先做边界判断,处理空数组或空字符串的特殊情况
- 遍历二维数组的每个位置,只要找到和目标字符串第一个字符匹配的位置,就启动递归回溯流程
- 递归回溯方法:
- 终止条件:当
currentIndex等于目标字符数组的长度时,说明所有字符都匹配成功,返回true - 边界检查:如果当前位置越界、已被访问、字符不匹配,直接返回
false - 标记访问:将当前位置标记为已访问,避免递归过程中重复使用同一个字符
- 递归探索:检查当前位置的上下左右四个方向,只要有一个方向能完成后续匹配,就返回
true - 回溯恢复:不管当前路径是否匹配成功,都要恢复当前位置的访问状态,保证其他搜索路径的正确性
- 终止条件:当
关键改进点对比你的原代码
- 不再单独遍历每个目标字符,而是从第一个匹配的位置开始,连续递归匹配下一个相邻字符
- 用
currentIndex跟踪当前需要匹配的目标字符位置,只有匹配成功才会递增索引 - 加入
visited数组,避免重复使用同一个数组位置(如果题目允许重复使用字符,你可以直接去掉这个数组) - 递归天然支持变长字符串的匹配需求,不需要写多层嵌套循环
内容的提问来源于stack exchange,提问作者koreankiwitea
相关产品推荐
相关产品推荐

