递归函数StackOverflowError

时间:2014-02-08 13:58:53

标签: java recursion

我正在编码僵尸感染城市中的人,而: 2:没有人 1:未感染的人 0:僵尸

僵尸会感染僵尸周围的所有正常人。 下面是我的Java程序,但我收到错误:StackOverflowError。

public class InfectGame {

/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub

    int a[][] = { { 1, 1, 1, 1, 2, 2, 2, 1, 1, 0 },
            { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 2, 1, 1, 2, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 0, 1, 1, 1, 2, 1 },
            { 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 2, 2, 2, 1, 1, 1, 1, 1, 1, 2 }, };

    int i = 0;
    int j = 0;
    for (i = 0; i < 10; i++) {
        for (j = 0; j < 10; j++) {

            if (a[i][j] == 0) {
                run_test(i, j, a, 0, 10);
            }
        }
    }

    i = 0;
    j = 0;
    for (i = 0; i < 10; i++) {
        System.out.print("\n");
        for (j = 0; j < 10; j++) {
            System.out.print(a[i][j] + " ");
        }
    }

}

public static void run_test(int x, int y, int a[][], int v, int size) {

    if ((x < 0) || (x >= size))
        return;
    if ((y < 0) || (y >= size))
        return;
    // System.out.print(a[x][y] + " ");
    // a[x][y] = v;
    if (a[x][y] != 2) {
        a[x][y] = v;
        if (x + 1 < size) {
            run_test(x + 1, y, a, v, size);
        }
        if (x > 0) {
            run_test(x - 1, y, a, v, size);
        }
        if (y + 1 < size) {
            run_test(x, y + 1, a, v, size);
        }
        if (y > 0) {
            run_test(x, y - 1, a, v, size);
        }
    }

}

}


    Exception in thread "main" java.lang.StackOverflowError
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)
        at InfectGame.run_test(InfectGame.java:55)
        at InfectGame.run_test(InfectGame.java:58)

............................................... .........

3 个答案:

答案 0 :(得分:1)

递归仅在您具有终止条件时才有效。 你没有它们。看看你的代码的这一部分:

    if (x + 1 < size) {
        run_test(x + 1, y, a, v, size);
    }
    if (x > 0) {
        run_test(x - 1, y, a, v, size);
    }

第一个if语句将递归,直到你在当前行的网格结束时。此时,它将转到第二个if语句并再次递归,但向后退一步。但是在下一次递归时,它将再次向右迈出一步,无限期。

这就是您收到错误的原因 - 您永远不会终止递归。

现在您已经解释过您正在尝试填充洪水,我可以看到您需要哪种终止条件:

if (a[x][y] != 2) {

应该是:

if (a[x][y] != 2 && a[x][y] != v) {

否则你会一遍又一遍地用僵尸填充相同的方块。

但是想一想你的僵尸问题,它与普通填充有点不同。在填充中,如果像素已经具有您想要的颜色,则可以停止递归。 对于第一个僵尸来说不是真的僵尸 - 从这个僵尸它扩散开来。所以第一次迭代不应该检查它是否已经是一个僵尸,但是任何进一步的递归迭代应该检查,否则它不会终止。

你可以这样做:

public static void run_test(int x, int y, int a[][], int v, int size, boolean first) {
    if ((x < 0) || (x >= size))
        return;
    if ((y < 0) || (y >= size))
        return;
    if (a[x][y] != 2 && (first || a[x][y] != v)) {
        a[x][y] = v;
        if (x + 1 < size) {
            run_test(x + 1, y, a, v, size, false);
        }
        if (x > 0) {
            run_test(x - 1, y, a, v, size, false);
        }
        if (y + 1 < size) {
            run_test(x, y + 1, a, v, size, false);
        }
        if (y > 0) {
            run_test(x, y - 1, a, v, size, false);
        }
    }
}

主方法的调用应为:

    run_test(i, j, a, 0, 10, true);

答案 1 :(得分:0)

你被困在这里:

    if (x + 1 < size) {
        run_test(x + 1, y, a, v, size);
    }
    if (x > 0) {
        run_test(x - 1, y, a, v, size);
    }

因为x总是第一个或第二个if条件。

答案 2 :(得分:0)

您应该使用更好的变量名称。使用描述变量而不是x,y,z的东西。