繁体   English   中英

创建一个 * n 正方形并使所有边的总和相同

[英]Creating a n * n square and making the sum of all sides the same

我需要一些帮助才能让我的代码正常工作; 我是 Java 的新手,所以请原谅我的任何不良做法。 我没有收到任何错误: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 5 at MagicSquare.main(MagicSquare.java:22)

我不确定如何使行和列环绕。

import java.util.Scanner;
    
    
    public class MagicSquare {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
    
            System.out.print("Enter an odd number: ");
            int n = in.nextInt();
            int[][] magicSquare = new int[n][n];
    
            for (int i = 0; i < n; i++) {
                for(int j = 0; j < n; j++) {
                    magicSquare[i][j] = 0;
                }
            }
    
            int x = 1;
            int y = (n + 1) / 2;
    
            for (int i = 0; i < (n * n); i++) {
                if (magicSquare[x - 1][y - 1] == 0) {
                    x -= 1;
                    y -= 1;
                }
                else {
                    x += 1;
                    y = y;
                }
                magicSquare[x][y] = i;
            }
            for(int i=0; i < n; i++){
                for(int j=0; j < n; j++){
                    System.out.print(magicSquare[i][j] + " ");
                }
                System.out.print("\n");
            }
        }
    }

你有三个问题。

  1. Java 中的数组索引从 0 开始,而不是从 1 开始。因此,用 0 初始化 x,用 (n+1)/2-1 初始化 y。

  2. 您需要包装索引。 例如,如果您移动到第 -1 列,则必须实际移动到第 n-1 列。 或者,如果您将 1 添加到 x 并尝试移动到第 n 行,您实际上必须将 go 到第 0 行(因为请记住 - 最后一行是数字 n-1)。

  3. 您实际上应该使用 System.out.print 打印构造的数组。

您只是将数据设置为magicSquare 您需要在main方法的最后打印它:

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

该算法假定行和列的环绕,因此您不能像算法中那样只执行x=x-1y=y-1 根据Alex 的回答,您需要在代码中进行以下更改:

int x = 0;
int y = ((n + 1) / 2) - 1;
        
for (int i = 0; i < (n * n); i++) {
    int tempX = (x == 0) ? n - 1 : x - 1; //x==0 implies wrap around
    int tempY = (y == 0) ? n - 1 : y - 1; //y==0 implies wrap around
    if (magicSquare[tempX][tempY] == 0) {
        x = tempX;
        y = tempY;
    }
    else {
        x = (x + 1) % n; // equivalent to (x == n-1) ? 0 : x + 1;
        y = y;
    }
    magicSquare[x][y] = i;
}

该算法中最棘手的事情是在包装它们时提供适当的索引,以防止当x低于 0 或高于n - 1时出现ArrayIndexOutOfBoundsException

这可以通过以下方式实现:

static int[][] magicSquare(int n) {
    int[][] square = new int[n][n];
    // x and y shifted by 1 because array indexes are 0 based
    int x = 0;
    int y = (n -1)/2;

    square[x][y] = 1;
    for (int i = 2; i <= n * n; i++) {
        // calculating next indexes x - 1 and y - 1
        int nx = x - 1;
        int ny = y - 1;
        // wrap indexes below 0
        if (nx < 0) nx = n - 1;
        if (ny < 0) ny = n - 1;

        if (square[nx][ny] == 0) {
            x = nx; y = ny;
        } else {
            x++;
            // wrap index above n - 1
            if (x >= n) x = 0;
        }
        square[x][y] = i;
    }
    return square;
}

正方形的打印可以移动到单独的方法中:

static void printSquare(int[][] square) {
    int maxLen = Integer.toString(square.length * square.length).length();
    String format = "%" + maxLen + "d  "; // align all numbers when printing the square
    for (int i = 0; i < square.length; i++) {
        for (int j = 0; j < square.length; j++) {
            System.out.printf(format, square[i][j]);
        }
        System.out.println();
    }
}

测试:

public static void main(String ... args) {
    printSquare(magicSquare(3));
    System.out.println("=======");
    printSquare(magicSquare(5));
}

Output

6  1  8  
7  5  3  
2  9  4  
=======
15   8   1  24  17  
16  14   7   5  23  
22  20  13   6   4  
 3  21  19  12  10  
 9   2  25  18  11 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM