Reputation: 38
I Have a recursive flood fill of legal neighbours in matrix ( legal neighbour is a neighbour with same color), the flood is not filling all the legal neighbours in the array.
the board I`m using for testing is :
int[][] map={{4,0,0,0},
{0,4,0,0},
{0,4,0,0},
{0,4,0,0}};
fill(map,1,1,9,4);// calling to function.
the output is :
4000
0900
0900
0900
Edit If i`m changing the map to:
int[][] map={{4,0,0,0},
{4,4,0,0},
{0,4,0,0},
{0,4,0,0}};
The output will be:
4000
4900
0900
0900
The two left 4 number need to be filled too.
and my recursive function is :
public static void fill(int[][] map, int row, int col, int color,int oldColor)
{
System.out.println("row is: "+row+"col is:"+col);
if ((row <= 0) || (row >= map.length) || (col <= 0) || (col >= map.length) ) return;
if(map[row][col]==color)
return;
if(map[row][col]==oldColor)
{
map[row][col]=color;
}
if(col+1<=map.length)
fill(map, col+1, row,color,oldColor);
if((col-1)<=0)
fill(map,col-1, row,color,oldColor);
if(row+1<=map.length)
fill(map, col, row+1,color,oldColor);
if((row-1)<=0)
fill(map, col, row-1,color,oldColor);
}
Changing the code
public static void fill(int[][] map, int row, int col, int color,int oldColor) {
System.out.println("row is: "+row+"col is:"+col);
if ((row < 0) || (row > map.length) || (col < 0) || (col > map.length) || map[row] [col]!=oldColor ) return;
if(map[row][col]==color)
return;
if(map[row][col]==oldColor)
{
map[row][col]=color;
}
fill(map, col, row-1,color,oldColor);
fill(map, col+1, row,color,oldColor);
fill(map, col, row+1,color,oldColor);
fill(map,col-1, row,color,oldColor);
}
The output is now:
9000
9900
0900
0400
Upvotes: 0
Views: 4135
Reputation: 3286
This is not best answer, but i can't delete my submission.
public class Fill
{
public static void fill(int[][] map, int col, int row, int color,int oldColor)
{
System.out.println("row is: "+row+"col is:"+col);
if ((row <= 0) || (row >= map.length) || (col <= 0) || (col >= map.length) ) return;
if(map[row][col]==color)
return;
if(map[row][col]==oldColor)
{
map[row][col]=color;
}
if(col+1<=map.length) {
fill(map, col+1, row,color,oldColor);
}
if((col-1)<=0) {
fill(map,col-1, row,color,oldColor);
}
if(row+1<=map.length) {
fill(map, col, row+1,color,oldColor);
}
if((row-1)<=0) {
fill(map, col, row-1,color,oldColor);
}
}
public static void main(String pArgs[])
{
int[][] map={{4,0,0,0},
{0,4,0,0},
{0,4,0,0},
{0,4,0,0}};
printMap(map);
fill(map,1,1,9,4);// calling to function.
printMap(map);
}
static void printMap(int[][] map)
{
for (int i=0; i < 4; i++) {
System.out.print("{");
for (int j=0; j<4; j++) {
System.out.print( map[i][j] + "," );
}
System.out.println("}");
}
}
}
Upvotes: 0
Reputation: 11543
You have several mistakes. First of all, your guard excludes row 0 and column 0, so that's one reason why you don't get the result you expect.
Now, fixing that you will get a stack overflow since you will try to fill all neighbours, no matter which color they have. That means that you will visit all cells with color 0 forever. You only want to fill neighbours that have the oldColor.
Last, your method expects the arguments row, column, but you recursivly call it with column, row, so you switch the indexes for each stack level.
Fixing that you can get a simpler method without a guarding if. If you expect different length on your rows, then you need to add the guard again.
Showing with a self contained example that prints the maps before and after filling them.
public class FloodFill {
static int[][] map1 ={{4,0,0,0}, {4,4,4,4}, {0,4,0,4}, {0,4,0,0}};
static int[][] map2 ={{0,4,4,4}, {0,4,0,4}, {0,4,0,4}, {9,9,9,4}};
public static void fill(int[][] map, int row, int col, int color, int oldColor) {
if (map[row][col] == oldColor) {
map[row][col] = color;
if (col + 1 < map[row].length)
fill(map, row, col + 1, color, oldColor);
if (col > 0)
fill(map, row, col - 1, color, oldColor);
if (row + 1 < map.length)
fill(map, row + 1, col, color, oldColor);
if (row > 0)
fill(map, row - 1, col, color, oldColor);
}
}
public static void main(String[] args) {
floodfill(map1);
floodfill(map2);
}
private static void floodfill(int[][] map) {
show(map, "Initial");
fill(map, 1, 1, 9, 4);
show(map, "Filled");
}
private static void show(int[][] map, String label) {
System.out.println(label);
for (int[] row : map) {
for (int val : row) {
System.out.print(val + " ");
}
System.out.println();
}
}
}
An alternative fill with a guard which then also handles rows with different lengths.
public static void fill2(int[][] map, int row, int col, int color, int oldColor) {
if (row < 0 || row >= map.length || col < 0 || col >= map[row].length)
return;
if (map[row][col] == oldColor) {
map[row][col] = color;
fill2(map, row, col + 1, color, oldColor);
fill2(map, row, col - 1, color, oldColor);
fill2(map, row + 1, col, color, oldColor);
fill2(map, row - 1, col, color, oldColor);
}
}
Upvotes: 1