Magic Square程序中的StackOverflowError,用于检查Square是否为魔术

时间:2018-12-17 04:13:20

标签: java recursion stack-overflow magic-square

我想我要讲到重点了:我的计算机科学老师给了我们一个作业,他希望我们创建一个程序,该程序生成一个3×3的魔术方块(表示该方块的所有行,列和对角线必须等于15)。他希望我们使用常规数组(一个一维数组,而不是二维数组),并至少具有两个功能-一个是递归的,可以生成或改组正方形,而另一个仅检查正方形是否为魔术。该程序应返回并打印一个魔术方块,不需要用户输入。

这是我的代码(我将其放在第一位,因为我将遇到的问题更容易解释(如果将其放在第一位;请跳至最后的实际问题):

ListPlot[Re[orderedpairs]]

因此,我遇到的问题是程序在经过一定次数后停止对正方形进行拖曳处理。函数shuffleSquare和checkIfMagic都可以工作,在重新组合 n 次之后,它只是给出了stackOverflowError。我测试了一下是否删除了CheckIfMagic函数中的某些限制(例如,我尝试了public class MagicSquare { public static void main(String[] args) { // main stub, get user input here int[] square = {1, 2, 3, 4, 5, 6, 7, 8, 9}; //int[] test = {2, 7, 6, 9, 5, 1, 4, 3, 8}; //printMagicSquare(test); shuffleSquare(square, 0); printMagicSquare(square); } public static int[] shuffleSquare(int[] square, int count) { // shuffles array Random randGen = new Random(); if(count >= square.length-1) { return square; } else { int index = randGen.nextInt(square.length - 1) + 0; int temp = square[count]; square[count] = square[index]; square[index] = temp; shuffleSquare(square, count + 1); } return square; } public static boolean checkIfMagic(int[] square) { // returns true or false for whether or not inputted array is a magic square int MAGICNUM = 15; int row1 = square[0] + square[1] + square[2]; //System.out.println(square[0] + " " + square[1] + " " + square[2]); int row2 = square[3] + square[4] + square[5]; //System.out.println(square[3] + " " + square[4] + " " + square[5]); int row3 = square[6] + square[7] + square[8]; //System.out.println(square[6] + " " + square[7] + " " + square[8] + "\n"); int col1 = square[0] + square[3] + square[6]; int col2 = square[1] + square[4] + square[7]; int col3 = square[2] + square[5] + square[8]; int diag1 = square[0] + square[4] + square[8]; int diag2 = square[2] + square[4] + square[6]; if(row1 == MAGICNUM && row2 == MAGICNUM && row3 == MAGICNUM && col1 == MAGICNUM && col2 == MAGICNUM && col3 == MAGICNUM && diag1 == MAGICNUM && diag2 == MAGICNUM) { return true; } else { return false; } } public static void printMagicSquare(int[] square) { // prints out magic square boolean isMagic = checkIfMagic(square); // check if square is magic (if it is, print it, if not then re-shuffle it and re-check it) if(isMagic == true) { System.out.println("Magic Square: "); for(int count = 0; count < square.length; count ++) { if(count == 3 || count == 6) { System.out.println(); System.out.print(square[count] + " "); } else { System.out.print(square[count] + " "); } } System.out.println("\n"); } else { shuffleSquare(square, 0); printMagicSquare(square); } } } ),但是这样做没有。相反,它输出的是确切的内容:一个正方形,行的总和等于15。当代码为if(row1 == MAGICNUM && row2 == MAGICNUM && row3 == MAGICNUM)时,它开始显示stackOverflowError。但是,由于正方形必须是魔术的(同样,所有行,列和对角线的总和等于相同的值),所以我不能使用它。

我想我的主要问题是如何解决此错误,以便继续进行改组直到返回一个魔术方块,以及是否有更好的地方或方法将其重新改组为魔术为止。

>

1 个答案:

答案 0 :(得分:0)

尝试一下:

public class MagicSquare {
    public static void main(String[] args) {
        // main stub, get user input here
        int[] square = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        printMagicSquare(square);
    }
    static Random randGen = new Random();
    public static void shuffleSquare(int[] square, int i) {
        if (i > 0) {
            int index = randGen.nextInt(i);
            int temp = square[index];
            square[index] = square[i];
            square[i] = temp;
            shuffleSquare(square, i - 1);
        }
    }

    public static boolean checkIfMagic(int[] square) {
        // returns true or false for whether or not inputted array is a magic square
        int MAGICNUM = 15;

        int row1 = square[0] + square[1] + square[2];
        //System.out.println(square[0] + " " + square[1] + " " + square[2]);
        int row2 = square[3] + square[4] + square[5];
        //System.out.println(square[3] + " " + square[4] + " " + square[5]);
        int row3 = square[6] + square[7] + square[8];
        //System.out.println(square[6] + " " + square[7] + " " + square[8] + "\n");

        int col1 = square[0] + square[3] + square[6];
        int col2 = square[1] + square[4] + square[7];
        int col3 = square[2] + square[5] + square[8];

        int diag1 = square[0] + square[4] + square[8];
        int diag2 = square[2] + square[4] + square[6];

        if(row1 == MAGICNUM && row2 == MAGICNUM && row3 == MAGICNUM && col1 == MAGICNUM && col2 == MAGICNUM && col3 == MAGICNUM && diag1 == MAGICNUM && diag2 == MAGICNUM) {
            return true;
        }
        else {
            return false;
        }
    }

    public static void printMagicSquare(int[] square) {
        while (!checkIfMagic(square)){
            shuffleSquare(square, square.length - 1);
        }

        System.out.println("Magic Square: ");
        for(int count = 0; count < square.length; count ++) {
            if(count == 3 || count == 6) {
                System.out.println();
                System.out.print(square[count] + " ");
            }
            else {
                System.out.print(square[count] + " ");
            }
        }
        System.out.println("\n");
    }
}

仅在变量超出范围后才释放局部变量的堆栈存储器。当您在printMagicSquare中调用printMagicSquare时。调用方的参数仍在范围内,因此不会释放内存。运行时在旧框架之上创建新的堆栈框架,以存储被调用方的局部变量和参数。然后,这一过程会不断重复,直到一个printMagicSquare找到答案或当我们耗尽堆栈内存时。因为shuffleSquare不起作用,所以只有一种方法。

    while (!checkIfMagic(square)){
        shuffleSquare(square, square.length - 1);
    }

这一步不进行递归调用,即使它永远运行,也可以使栈顶保持稳定。