Java 在网格中递归查找单词
为了在网格上找到一个单词,我正在研究一个算法问题 我的解决方案是首先在网格中找到单词的第一个字母,如果找到了,则递归地遍历8个方向,直到单词的每个索引都与网格索引匹配,然后返回字符串。附件是我的代码: 我跟踪我当前的x和y位置,然后当且仅当单词的索引与网格中的索引匹配时,增加字符串的位置。但是,在这段代码中,我的递归出现了一些错误,导致堆栈溢出:Java 在网格中递归查找单词,java,recursion,grid,word,Java,Recursion,Grid,Word,为了在网格上找到一个单词,我正在研究一个算法问题 我的解决方案是首先在网格中找到单词的第一个字母,如果找到了,则递归地遍历8个方向,直到单词的每个索引都与网格索引匹配,然后返回字符串。附件是我的代码: 我跟踪我当前的x和y位置,然后当且仅当单词的索引与网格中的索引匹配时,增加字符串的位置。但是,在这段代码中,我的递归出现了一些错误,导致堆栈溢出: public static void findWord(int row, int col, char[][] grid, String w) {
public static void findWord(int row, int col, char[][] grid, String w) {
int rowLength = row;
int colLength = col;
char[] word = w.toCharArray();
for(int j = 0; j < colLength; j++) {
for(int i = 0; i < rowLength; i++) {
// Check if first index of word is in this location
if(word[0] == grid[j][i]) {
// Iterate through each 8 directions to find the next word
for(int dir = 0; dir < 8; dir++) {
recursiveFind(i, j, i, j, dir, 0, word, grid, rowLength, colLength);
}
}
}
}
}
public static boolean recursiveFind(
int initialX,
int initialY,
int currentX,
int currentY,
int dir,
int currentPos,
char[] word,
char[][] grid,
int rowLength,
int colLength)
{
// base case is if currentPos == length of word
if(word.length == currentPos) {
System.out.println("Initial: " + initialX + " " + initialY);
System.out.println("Final: " + currentX + " " + currentY);
}
if(dir == 0) { // 1
currentX = currentX; // 0
currentY -= 1; // -1
} else if(dir == 1) {
currentX += 1; // 1
currentY -= 1; // -1
} else if(dir == 2) {
currentX += 1; // 1
currentY = 0; // 0
} else if(dir == 3) {
currentX += 1; // 1
currentY += 1; // 1
} else if(dir == 4) {
currentX = currentX; // 0
currentY += 1; // 1
} else if(dir == 5) {
currentX -= 1; // -1
currentY += 1; // 1
} else if(dir == 6) {
currentX -= 1; // -1
currentY = currentY; // 0
} else {
currentX -= 1; // -1
currentY -= 1; // -1
}
if(currentX < 0 ||
currentX == rowLength ||
currentY < 0 ||
currentY == colLength ||
grid[currentY][currentX] != word[currentPos]){
return false;
}
return recursiveFind(initialX, initialY, currentX, currentY, dir, currentPos + 1, word, grid, rowLength, colLength);
}
我目前正试图把一些调试语句,看看是什么问题,但是,如果有人愿意给我一些帮助,这将是非常感谢
编辑:
在基本情况下,我通过返回true
修复了堆栈溢出问题。但是,我的结果如下所示,它们没有返回我想要的预期值
Initial X: 3, Initial Y: 0, Dir: 0, Current X: 3, Current Y: 0
Initial X: 3, Initial Y: 0, Dir: 1, Current X: 3, Current Y: 0
Initial X: 3, Initial Y: 0, Dir: 2, Current X: 3, Current Y: 0
Initial X: 3, Initial Y: 0, Dir: 3, Current X: 3, Current Y: 0
Initial X: 3, Initial Y: 0, Dir: 4, Current X: 3, Current Y: 0
Initial X: 3, Initial Y: 0, Dir: 5, Current X: 3, Current Y: 0
Initial X: 3, Initial Y: 0, Dir: 6, Current X: 3, Current Y: 0
从第一眼看,我认为问题可能是当currentpos达到字长时,您没有终止递归,因此它将一直运行,直到溢出为止。基本情况应该结束递归,但是如果不满足返回false的条件,您的情况将继续 编辑: 我很确定目录2的条件应该是:
else if(dir == 2) {
currentX += 1; // 1
currentY = currentY; // 0
}
否则,您将重新启动当前的Y,就像现在一样
编辑:
此外,您不应该在递归开始时将currentpos作为0发送,因为它将再次与单词的第一个字母进行比较。递归应该开始与第二个字符进行比较,因为您已经比较了第一个字符。不要忘记添加返回值true,您的程序应该会运行。我刚在我的电脑上试过 我将其更改为检查当前位置是否正确,然后继续搜索。 否则,返回false
public static boolean recursiveFind(
int initialX,
int initialY,
int currentX,
int currentY,
int dir,
int currentPos,
char[] word,
char[][] grid,
int rowLength,
int colLength) {
// base case is if currentPos == length of word
if (word.length == currentPos) {
System.out.println("Initial: " + initialX + " " + initialY);
System.out.println("Final: " + currentX + " " + currentY);
return true;
}
if (currentX >= 0 && currentX < rowLength && currentY >= 0 && currentY < colLength && grid[currentY][currentX] == word[currentPos]) {
if (dir == 0) { // 1
currentX = currentX; // 0
currentY -= 1; // -1
} else if (dir == 1) {
currentX += 1; // 1
currentY -= 1; // -1
} else if (dir == 2) {
currentX += 1; // 1
currentY = 0; // 0
} else if (dir == 3) {
currentX += 1; // 1
currentY += 1; // 1
} else if (dir == 4) {
currentX = currentX; // 0
currentY += 1; // 1
} else if (dir == 5) {
currentX -= 1; // -1
currentY += 1; // 1
} else if (dir == 6) {
currentX -= 1; // -1
currentY = currentY; // 0
} else {
currentX -= 1; // -1
currentY -= 1; // -1
}
return recursiveFind(initialX, initialY, currentX, currentY, dir, currentPos + 1, word, grid, rowLength, colLength);
}
return false;
}
或者你没有真正检查当前位置:p哦-看起来我遗漏了一个“返回真值!”我猜可能是这样的问题。有用吗?没有。它不会给我堆栈溢出错误,但它没有正确返回预期值。如果x或y超出边界,您的递归应该停止,但我没有看到您在任何地方考虑到这一点。如果最终目标是找到你所拥有的单词,为什么不将网格中的当前位置与正在查找的字符进行比较?我可能错了,但我不是使用
grid[currentY][currentX]!=word[currentPos]
?我要做的是,如果网格char和word char中有匹配项,它只会增加pos
变量。哇,布伦丹-谢谢!很高兴看到我在正确的轨道上,但我的一些操作顺序混淆了..重申一下,在我们增加/减少x和y的当前位置之前,我们已经检查了x和y的位置和有效性,对吗?是的,听起来正确。虽然我不确定这种方法是否比仅仅获取整行、整列、整条对角线并使用子字符串搜索单词要好(如果有的话):)实际上,这种方法的时间复杂度似乎相当高。前两个for循环直接解释了O(行*长度)。现在确定循环的递归和方向的复杂性。
public static boolean recursiveFind(
int initialX,
int initialY,
int currentX,
int currentY,
int dir,
int currentPos,
char[] word,
char[][] grid,
int rowLength,
int colLength) {
// base case is if currentPos == length of word
if (word.length == currentPos) {
System.out.println("Initial: " + initialX + " " + initialY);
System.out.println("Final: " + currentX + " " + currentY);
return true;
}
if (currentX >= 0 && currentX < rowLength && currentY >= 0 && currentY < colLength && grid[currentY][currentX] == word[currentPos]) {
if (dir == 0) { // 1
currentX = currentX; // 0
currentY -= 1; // -1
} else if (dir == 1) {
currentX += 1; // 1
currentY -= 1; // -1
} else if (dir == 2) {
currentX += 1; // 1
currentY = 0; // 0
} else if (dir == 3) {
currentX += 1; // 1
currentY += 1; // 1
} else if (dir == 4) {
currentX = currentX; // 0
currentY += 1; // 1
} else if (dir == 5) {
currentX -= 1; // -1
currentY += 1; // 1
} else if (dir == 6) {
currentX -= 1; // -1
currentY = currentY; // 0
} else {
currentX -= 1; // -1
currentY -= 1; // -1
}
return recursiveFind(initialX, initialY, currentX, currentY, dir, currentPos + 1, word, grid, rowLength, colLength);
}
return false;
}
if(currentX < 0 ||
currentX == rowLength ||
currentY < 0 ||
currentY == colLength ||
grid[currentY][currentX] != word[currentPos]){
return false;
}
if(dir == 0) { // 1
currentX = currentX; // 0
currentY -= 1; // -1
} else if(dir == 1) {
currentX += 1; // 1
currentY -= 1; // -1
} else if(dir == 2) {
currentX += 1; // 1
currentY = 0; // 0
} else if(dir == 3) {
currentX += 1; // 1
currentY += 1; // 1
} else if(dir == 4) {
currentX = currentX; // 0
currentY += 1; // 1
} else if(dir == 5) {
currentX -= 1; // -1
currentY += 1; // 1
} else if(dir == 6) {
currentX -= 1; // -1
currentY = currentY; // 0
} else {
currentX -= 1; // -1
currentY -= 1; // -1
}