【发布时间】:2018-12-19 00:10:29
【问题描述】:
我想我要直截了当:我的计算机科学老师给了我们一个作业,他希望我们创建一个程序来生成一个 3 x 3 幻方(意味着正方形的所有行、列和对角线)必须等于 15)。他希望我们使用一个常规数组(一个一维数组,而不是二维数组)并至少有两个函数——一个是递归的,用于生成或打乱正方形,另一个只是检查正方形是否是魔法。程序应该返回并打印一个魔方,不需要用户输入。
这是我的代码(我将其放在首位,因为如果将其放在首位,我遇到的问题会更容易解释;实际问题请跳到最后):
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);
}
}
}
所以,我遇到的问题是程序在一定次数后停止洗牌。函数 shuffleSquare 和 checkIfMagic 都可以工作,它只是在重新洗牌 n 次后给出 stackOverflowError。我测试了如果我删除了 checkIfMagic 函数中的一些限制(例如,我尝试了if(row1 == MAGICNUM && row2 == MAGICNUM && row3 == MAGICNUM)),它是否会这样做,但它没有。相反,它输出了它应该具有的确切内容:行总和等于 15 的正方形。当代码为 if(row1 == MAGICNUM && row2 == MAGICNUM && row3 == MAGICNUM && col1 == MAGICNUM && col2 == MAGICNUM && col3 == MAGICNUM) 时,它开始显示 stackOverflowError。但是,由于正方形必须是魔法(同样,所有行、列和对角线的总和都等于相同的值),我不能使用它。
我想我的主要问题是如何修复这个错误,以便它继续洗牌,直到它返回一个幻方,以及是否有更好的地方或方法来重新洗牌,直到它变幻为止。
【问题讨论】:
-
您需要在代码中添加一些 println,以查看您的递归停止条件永远不会实现以及原因。你的递归有点复杂,因为你有方法调用其他方法,然后调用它们自己和第一个方法。
-
@HovercraftFullOfEels 感谢您的提示!下次我发布问题时,我会记住这一点。
标签: java recursion stack-overflow magic-square