递归地在网格中找到一个单词

时间:2016-04-13 18:06:10

标签: java recursion grid word

我正在研究算法问题,以便在网格上找到一个单词。

我的解决方案包括首先在网格中找到单词的第一个字母,然后如果找到,则递归地遍历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

2 个答案:

答案 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,并且您的程序应该运行。我只是在我的电脑上试过它。