二维阵列程序中for循环的问题

时间:2014-02-13 16:45:05

标签: java arrays loops multidimensional-array

好的,所以我当前的任务让我制作了一个可以模仿渗透的程序,这意味着它必须读取一个数组,其中1表示空间是关闭的,0表示空间是打开的。接下来,它必须将阵列顶行的所有0改为2,表示正在倒入的液体。然后液体可以跟随0(代表流动),沿途将它们全部改为两个。液体可以向上,向下,向左和向右移动。不对角线。我的程序几乎正常工作,但for循环似乎没有超过数组的第一行。

public class Percolation2 {
    public static void main (String[] args) {
        int[][] filter1 = {{1,0,1,0,1,1,0}, 
                {1,0,1,1,1,0,0},
                {0,0,0,1,0,0,1},
                {1,1,0,1,1,1,1}, 
                {1,0,0,1,1,0,1},
                {1,0,1,0,1,0,1},
                {0,0,0,0,1,1,0}, 
                {1,1,1,0,1,0,1}};
        for(int i=0; i<7; i++) {
            if(filter1[0][i] ==0) {
                filter1[0][i] = 2;
            }
        }

        for ( int i = 0 ; i < filter1.length ; i++ ) {
            for ( int j = 0 ; j < filter1[i].length ; j++ ) {

                if ( filter1[i][j] == 0 )

                    if(i-1 > 0 && filter1[i-1][j] == 2)
                        filter1[i][j] = 2;

                    if(i+1 < 7 && filter1[i+1][j] ==2)
                        filter1[i][j] = 2;

                    if(j-1 > 0 && filter1[i][j-1]==2)
                        filter1[i][j] = 2;

                    if(j+1 < 7 && filter1[i][j+1] == 2)
                        filter1[i][j] = 2;
            }
        }

        for(int i = 0; i < filter1.length; i++) {
            for(int j = 0; j < filter1[i].length; j++) {
                System.out.print(filter1[i][j]);
                if(j < filter1[i].length - 1) System.out.print(" ");
            }
            System.out.println();
        }
    } 
}

我的输出如下:

2 2 2 2 2 2 2
1 0 1 1 1 0 0
0 0 0 1 0 0 1
1 1 0 1 1 1 1
1 0 0 1 1 0 1
1 0 1 0 1 0 1
0 0 0 0 1 1 0
1 1 1 0 1 0 1

所以你可以清楚地告诉它没有正确循环。

2 个答案:

答案 0 :(得分:0)

每次转动液体都可以移动一级。您的for语句是正确的,访问了数组的所有元素。你需要另一个循环来获得适当的转弯量。

我不想直接给你答案,因为这里有一个值得学习的教训,你需要有类似的东西:

//Init
boolean done = false;

while(!done) {

   for (int i = 0; i < filter1.length; i++) {
     for(int j = 0; j < filter1[i].length; j++) {
        if(filter1[i][j] == 0)
        ....
     }
   }

   //add the print matrix code here if you want it done after each turn.

   done = amIDone();
}

总体而言,您的代码结构非常糟糕。您应该使用数组长度的常量,并且还可以为两个双嵌套for循环定义方法。在最低限度,我将采用printMatrix()方法。

答案 1 :(得分:0)

我在这里看到几个问题:

1)您似乎在双 if(filter1[i][j] == 0)循环中的for后面的代码块周围留下了大括号。

2)在此之下,您对越境的检查不正确 if(i-1 > 0 && ...应为 if(i-1 >= 0 && ...。而if(j+1 < 7 && ... 应为if(j+1 < 8 && ...

3)在你的问题中,你说你的输出是2 2 2 2 2 2 2 ... 。但是您的代码会产生不同的结果,您的输出应该是1 2 1 2 1 1 2 ...。这就是我运行for(int i=0; i<7; i++) { if(filter1[0][i] == 0) { filter1[0][i] = 2; } }

时得到的结果

4)皮特暗示了这个问题。但更具体地说,你正在向下传递矩阵(2D数组)。没有能力提高液体(也没有左)。

让我们称这些项为单元格。当一个细胞变成液体时(也就是说它转向= 2),它应该将液体渗透到空的相邻细胞中(a.k.a。设定为0)。这听起来像是递归的呼吁,恕我直言!

一旦解决了前三个问题。将双for循环的有效负载放入递归函数,例如:

public void percolate(int x, int y) {
    if ( filter1[x][y] == 0 ) {
        if(x-1 >= 0 && filter1[x-1][y] == 2) filter1[x][y] = 2;
        if(x+1 < 7 && filter1[x+1][y] == 2) filter1[x][y] = 2;
        if(y-1 >= 0 && filter1[x][y-1] == 2) filter1[x][y] = 2;
        if(y+1 < 8 && filter1[x][y+1] == 2) filter1[x][y] = 2;
        if ( filter1[x][y] == 2 ) {
            if ( x-1 >= 0 ) percolate(x-1,y);
            if ( x+1 < 7 ) percolate(x+1,y);
            if ( y-1 >= 0 ) percolate(x,y-1);
            if ( y+1 < 8 ) percolate(x,y+1);
        }
    }
}

然后只需为双for循环中的每个单元格调用它。实际上,由于液体从顶部开始,我猜你只能为 second 行中的每个单元调用percolate。它将从那里渗透下来。

正如您可能看到的,这不是最有效的解决方案,它可以对某些单元格上的渗透进行双重/三重检查。但这是纤细的螺母和螺栓版本。

编辑:修正了类型,摆脱了不必要的布尔值。