我正在研究算法问题,以便在网格上找到一个单词。
我的解决方案包括首先在网格中找到单词的第一个字母,然后如果找到,则递归地遍历8个方向,直到单词的每个索引与网格索引匹配,并返回字符串。附上我的代码:
我跟踪当前的x和y位置,然后增加字符串的位置,当且仅当字符的索引与网格中的索引匹配时。但是,使用这段代码,我的递归导致堆栈溢出有问题:
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);
}
Main.java
char[][] myGrid = new char[][]{
{'H', 'Q', 'W', 'C', 'S'},
{'E', 'S', 'P', 'K', 'D'},
{'D', 'X', 'A', 'F', 'L'},
{'O', 'C', 'H', 'K', 'H'},
{'C', 'T', 'Y', 'C', 'A'},
};
String myWord = "CODE";
findWord(5, 5, myGrid, myWord);
我目前正在尝试使用一些调试语句来查看问题所在,但是,如果有人愿意就此提供一些帮助,我们将非常感谢!
编辑:
我在基本情况下修复了return true
的Stack Overflow问题。但是,我的结果如下,它们没有返回我想要的预期值。
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
答案 0 :(得分:1)
我更改了它以检查当前位置是否正确,然后继续搜索。 否则,返回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;
}
编辑:使用您的最新编辑,问题是您在检查当前位置之前更改了currentX / currentY。
这段代码:
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
}
否则你并没有真正检查当前的位置:P
答案 1 :(得分:0)
从第一眼看,我认为问题可能是当currentpos达到字长时你不会终止递归,所以它会继续运行直到它溢出。基本情况应该结束递归,但是如果不满足返回false的条件,你的继续进行。
编辑: 我很确定dir 2的条件应该是:
else if(dir == 2) {
currentX += 1; // 1
currentY = currentY; // 0
}
否则您正在重新启动当前的Y,就像现在一样
编辑: 此外,您不应该在递归开始时将currentpos作为0发送,因为它将再次与该单词的第一个字母进行比较。递归应该开始与第二个char进行比较,因为您已经比较了第一个char。不要忘记添加返回true,并且您的程序应该运行。我只是在我的电脑上试过它。