如何在 Java 中漂亮地打印 3D 阵列

How to pretty print a 3D array in Java

我有一个三维 int 数组,想以这种格式打印它:

[n,n,n] [n,n,n] [n,n,n]
[n,n,n] [n,n,n] [n,n,n]
[n,n,n] [n,n,n] [n,n,n]

[n,n,n] [n,n,n] [n,n,n]
[n,n,n] [n,n,n] [n,n,n]
[n,n,n] [n,n,n] [n,n,n]

[n,n,n] [n,n,n] [n,n,n]
[n,n,n] [n,n,n] [n,n,n]
[n,n,n] [n,n,n] [n,n,n]

我尝试使用下面的代码,但它没有正确打印,因为第二列和第三列必须附加到与第一列相同的行:

int[][][] hardestOne = {
    {{8, 0, 0, 0, 0, 3, 0, 7, 0}, {0, 0, 0, 6, 0, 0, 0, 9, 0}, {0, 0, 0, 0, 0, 0, 2, 0, 0}},
    {{0, 5, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 7, 0, 4, 5, 1, 0, 0}, {0, 0, 0, 7, 0, 0, 0, 3, 0}},
    {{0, 0, 1, 0, 0, 8, 0, 9, 0}, {0, 0, 0, 5, 0, 0, 0, 0, 0}, {0, 6, 8, 0, 1, 0, 4, 0, 0}}
};

public String toString() {
    String s = "";

    for (int i = 0; i < table.length; i++) {
        for (int j = 0; j < table[i].length; j++) {
            for (int k = 0; k < table[i][j].length; k++) {
                if (k == 2 || k == 5) {
                    s += table[i][j][k] + "\n";
                } else {
                    s += table[i][j][k] + "";
                }
            }
            s += "\n\n";
        }
        s += "\n";
    }

    return s;
}

更新: 我更改了示例数组以使其更具可读性。

更新 2: 用户@samurott 给出了非常好的答案,但存在这个问题:

考虑代表数组中第一个块的这三行

{{8, 0, 0}, {0, 0, 3}, {0, 7, 0}},
{{0, 0, 0}, {6, 0, 0}, {0, 9, 0}},
{{0, 0, 0}, {0, 0, 0}, {2, 0, 0}}

查看打印上方的那些行应该是这样的

[8,0,0] [0,0,0] [0,0,0]
[0,0,3] [6,0,0] [0,0,0]
[0,7,0] [0,9,0] [2,0,0]

但是当我使用他的代码打印它时它看起来像这样

[8,0,0] [0,0,3] [0,7,0]
[0,0,0] [6,0,0] [0,9,0]
[0,0,0] [0,0,0] [2,0,0]

你看我可以改变数组的所有位置,但以后会变得越来越混乱。

解决方案:参见下面用户@Alex R

的解决方案

我相信您要打印的是 4 维数组,而不是 3 维数组,因为您有 4 层分组。然而,这里是修改后的漂亮打印循环:

for (int i = 0; i < table.length; i++){
    for (int j = 0; j < table[i].length; j++){
        for (int k = 0; k < table[i][j].length; k++){
            s += "[";
            for (int l = 0; l < table[i][j][k].length; l++){
                s += table[i][j][k][l];
                if (l != table[i][j][k].length - 1){
                    s += ",";
                }
            }
            s += "]";
            if (k != table[i][j].length - 1){
                s += " ";
            }
        }
        s += "\n";
    }
    s += "\n";
}

这是修改后的值table我正在使用:

static int[][][][] table = {
        {
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
        },
        {
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
        },
        {
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
                {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
        },
};

我对您的代码做了很小的改动。问题是 k 循环了你的内部数据,你在几个地方放了一个换行符。我不认为那是你想要的。然后在 k 的每个循环之后添加更多换行符。我删除了多余的换行符,然后稍微摆弄一下让它变得漂亮。

public class X {

    int[][][] table = {
        {{1, 2, 3, 4, 5, 6, 7, 8, 9}, {11, 12, 13, 14, 15, 16, 17, 18, 19}, {21, 22, 23, 24, 25, 26, 27, 28, 29}},
        {{101, 102, 103, 104, 105, 106, 107, 108, 109}, {111, 112, 113, 114, 115, 116, 117, 118, 119}, {121, 122, 123, 124, 125, 126, 127, 128, 129}},
        {{201, 202, 203, 204, 205, 206, 207, 208, 209}, {211, 212, 213, 214, 215, 216, 217, 218, 219}, {221, 222, 223, 224, 225, 226, 227, 228, 229}},
    };

    public String toString() {
        String s = "";

        for (int i = 0; i < table.length; i++) {
            for (int j = 0; j < table[i].length; j++) {
                s += (j == 0) ? "[" : " [";


                for (int k = 0; k < table[i][j].length; k++) {
                    if (k > 0) {
                        s += ", ";
                    }
                    s += table[i][j][k];
                }
                s += "]";
            }
            s += "\n";
        }

        return s;
    }

    public static void main(String[] args) {
        X foo = new X();
        System.out.println(foo.toString() );
    }
}

$ javac X.java && java X
[1, 2, 3, 4, 5, 6, 7, 8, 9] [11, 12, 13, 14, 15, 16, 17, 18, 19] [21, 22, 23, 24, 25, 26, 27, 28, 29]
[101, 102, 103, 104, 105, 106, 107, 108, 109] [111, 112, 113, 114, 115, 116, 117, 118, 119] [121, 122, 123, 124, 125, 126, 127, 128, 129]
[201, 202, 203, 204, 205, 206, 207, 208, 209] [211, 212, 213, 214, 215, 216, 217, 218, 219] [221, 222, 223, 224, 225, 226, 227, 228, 229]

这是一个可重复使用的 3x3 矩阵解决方案。这仅在数组包含 0 到 9 的数字时有效。如果您还想支持其他整数,则需要额外的格式设置。

public final class TableFormatter {
private static final int[][][] TABLE = {
        {{8, 0, 0, 0, 0, 3, 0, 7, 0}, {0, 0, 0, 6, 0, 0, 0, 9, 0}, {0, 0, 0, 0, 0, 0, 2, 0, 0}},
        {{0, 5, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 7, 0, 4, 5, 1, 0, 0}, {0, 0, 0, 7, 0, 0, 0, 3, 0}},
        {{0, 0, 1, 0, 0, 8, 0, 9, 0}, {0, 0, 0, 5, 0, 0, 0, 0, 0}, {0, 6, 8, 0, 1, 0, 4, 0, 0}}
};

public static void main(String[] args) {
    TableFormatter formatter = new TableFormatter(TABLE);
    System.out.println(formatter.toString());
}

private final int[][][] array3d;

public TableFormatter(int[][][] array3d) {
    this.array3d = array3d;
}

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    for (int[][] array2d : array3d) {
        append2dArray(builder, array2d);
        builder.append('\n');
    }
    return builder.toString();
}

private void append2dArray(StringBuilder builder3d, int[][] array2d) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            StringBuilder builder2d = new StringBuilder("[");
            for (int k = 0; k < 3; k++) {
                builder2d.append(array2d[j][(i * 3) + k]).append(',');
            }
            builder2d.deleteCharAt(builder2d.length() - 1).append("]\t");
            builder3d.append(builder2d);
        }
        builder3d.append('\n');
    }
}
}

输出:

[8,0,0] [0,0,0] [0,0,0] 
[0,0,3] [6,0,0] [0,0,0] 
[0,7,0] [0,9,0] [2,0,0] 

[0,5,0] [0,0,7] [0,0,0] 
[0,0,0] [0,4,5] [7,0,0] 
[0,0,0] [1,0,0] [0,3,0] 

[0,0,1] [0,0,0] [0,6,8] 
[0,0,8] [5,0,0] [0,1,0] 
[0,9,0] [0,0,0] [4,0,0] 

如果您想要支持一般矩阵,则必须将维度作为参数传递给构造函数并更新循环变量,以便它们使用该维度。