好的,所以我当前的任务让我制作了一个可以模仿渗透的程序,这意味着它必须读取一个数组,其中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
所以你可以清楚地告诉它没有正确循环。
答案 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
。它将从那里渗透下来。
正如您可能看到的,这不是最有效的解决方案,它可以对某些单元格上的渗透进行双重/三重检查。但这是纤细的螺母和螺栓版本。
编辑:修正了类型,摆脱了不必要的布尔值。