Java中“镜像”一个二维数组

3

我尝试在Java中创建一个“二维”数组,用介于1到6之间的随机数(编辑:我的意思是0到5,因为代码当前如此 - 抱歉)填充它自己。然而,我希望这些数字能够在一条最佳拟合线上“镜像”,就像处理图表数据一样。例如,如果指数[1] [4]处的数字为3.0,则我希望[4] [1]处的数字也为3.0。目前我有处理这个的代码片段,代码中另一个位置已经确定了数组长度为6:

Random random = new Random();

        int n = array.length;

        double [][] populationArray = new double [n][n];

        for (int i=0; i<populationArray.length; i++){
            for (int j=0; j<populationArray[i].length; j++) {
                populationArray[i][j] = random.nextInt(6);
                if (populationArray[i][j] != 0) {
                    populationArray[j][i] = populationArray[i][j];
                }
            }
        }

        for (double[] p : populationArray) {
            System.out.println(Arrays.toString(p));
        }

目前,这将打印为:

[0.0, 1.0, 2.0, 1.0, 5.0, 2.0]
[1.0, 3.0, 5.0, 1.0, 3.0, 1.0]
[2.0, 5.0, 4.0, 1.0, 4.0, 1.0]
[1.0, 1.0, 1.0, 4.0, 2.0, 2.0]
[5.0, 3.0, 0.0, 2.0, 4.0, 4.0]
[2.0, 1.0, 0.0, 0.0, 4.0, 1.0]

正如您所看到的,一些数字反映出来了,而一些则没有(我怀疑那些反映出来的纯粹是运气),我对此的逻辑感到困惑。如果您有任何建议,我将不胜感激-如果这个问题已经在其他地方得到解答,我也可以接受链接,因为我自己找不到。

谢谢。


if(populationArray[i][j] != 0) 看起来是你的问题。它基本上是随机反映还是不反映。此外,您正在用随机数覆盖先前反射的值。 - Luke Briggs
除了0.0值数组实际上像你说的那样是镜像的。删除if条件,它应该可以正常工作。 - reden
1
你的循环覆盖了数组中的所有位置,但它们应该只覆盖数组位置的一半 - Timothy Truckle
3个回答

2

由于if(populationArray[i][j] != 0)只有不为0的值才会被镜像。如果您删除if语句,代码将正常工作。

此外,random.nextInt(6)会生成一个介于0(包括)和6(不包括)之间的整数,因此会生成0、1、2、3、4或5。

因此,要生成1-5(包括在内)之间的数字,您需要执行random.nextInt(5)+1。

因此,for循环将变为:

for (int i=0; i<populationArray.length; i++){
        for (int j=0; j<populationArray[i].length; j++) {
            populationArray[i][j] = random.nextInt(5)+1;
            populationArray[j][i] = populationArray[i][j];
    }
}

然而,我想指出的是所有位置都会随机赋值两次。对于创建一个6x6的数组来说,差别不太明显。但如果你计划创建更大/更多的数组,我建议你优化你的代码,避免给数组中的每个位置赋值两次。
你可以通过将 j<populationArray[i].length 改为 j<=i 来进行优化:
for (int i=0; i<populationArray.length; i++){
    for (int j=0; j<=i; j++) {
        populationArray[i][j] = random.nextInt(5)+1;
        populationArray[j][i] = populationArray[i][j];
    }
}

1
但是需要注意的是,这样做会花费两倍的时间。虽然在这里不是问题,但还是应该提一下。 - Timothy Truckle
3
值得一提的是,循环遍历数组的一半也使用了稍微少一些的代码。只需将 j<populationArray[i].length 替换为 j<=i 即可。 - Luke Briggs
@Luke,这只导致[0][0]、[1][1]、[2][2]等点被填充,其余为0。不确定我错了什么? - Juniper
2
@Juniper,听起来你可能把两个答案结合在一起了——只有当你做了类似于j=i;j<=i;j++的事情时,它才会访问主对角线(“中间”)——这是不正确的。也就是说,应该是for (int j=0; j<=i; j++) { - Luke Briggs
1
@Juniper 没问题 - 我建议接受/点赞/两者都做 :) - Luke Briggs
显示剩余3条评论

0

你的问题出在这几行代码上

populationArray[i][j] = random.nextInt(6);
if(populationArray[i][j] != 0) {
    populationArray[j][i] = populationArray[i][j];
}

如果populationArray[i][j] = random.nextInt(6);返回0,那么它将不会被反映。我怀疑你想要populationArray[i][j] = random.nextInt(5)+1;这将返回1到6之间的随机数。
奖励:你的代码现在可以工作了,但实际上它每个单元格都写了两次。它将写入[1,4]并镜像到[4,1],但然后它将继续循环并覆盖[4,1]并镜像到[1,4],为了解决这个问题,您需要添加一个检查以查看它是否为0才能写入它。巧合的是,这只是把你的if语句向上移动一行。
    for (int i=0; i<populationArray.length; i++){
        for (int j=i; j<populationArray[i].length; j++) {
            populationArray[i][j] = random.nextInt(5)+1;
            populationArray[j][i] = populationArray[i][j];
        }
    }

编辑:根据Luke的评论更改了解决方案。请注意第二个for语句中int j=i的变化。


1
我认为这有点像黑客 - 最好只循环数组的一半(即类似于j<=i的东西)。 - Luke Briggs
我确实想在那里放置0,以便它指定0到5之间的随机双精度数字。我认为只是我的逻辑有问题 - 我假设它会用0填充索引,除非另有规定,因此该部分不需要反映。我不知道为什么没有想到反射所有这些。感谢您对效率的注意 - 这从来不是我的强项,但您的解释非常合理。 - Juniper
基于Luke Briggs的评论,我会更改第二个for循环,使其仅迭代数组的一半。 - Joe
1
无论是 for (int j=0; j<=i; j++) 还是 for (int j=i; j<populationArray[i].length; j++),都可以实现这个功能;一个是生成上半部分并反射到下半部分;另一个是生成下半部分并反射到上半部分。 - Luke Briggs

-1

如果你的数组变得更大,你可能想节省时间,不要设置每个元素两次。因此,你的内部循环不应该运行到 populationArray[i].length

for (int i=0; i<populationArray.length; i++){
        for (int j=0; j<populationArray[i].length-i; j++) {
            populationArray[i][j] = random.nextInt(6);
            int oppositI = populationArray.length -1 - i;
            int oppositJ = populationArray[i].length -1 - j;
            populationArray[oppositI][oppositJ] = populationArray[i][j];
    }
}

这里假设你的populationArray是一个正方形。否则会变得更加复杂...


我相当确定这是不正确的 - 这会导致数组的一部分永远不被访问。正确的形式是j<=i而不是j<populationArray[i].length-i - Luke Briggs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接