我正在尝试制作一个洪水填充算法,该算法计算墙壁所包围的空白空间的数量。 我使用的是2D字符串数组,墙由'#34; 1"表示。并且空格为空。 理想情况下,算法应该检查数组中的每个String,返回位置map [x] [y]中的String不为null的任何点,并计算由wall包围的空白空间的数量。 然而,在那一刻我得到的房间数量非常长,不知道我哪里出错了。
public static void floodFill(int x, int y, String oldChar, String newChar){
x = 0;
y=0;
if (x < 0 || y < 0 || x > map.length || y > map[0].length ){
return;
}
if (map[x][y] != oldChar){
return;
}
map[x][y] = newChar;
// Recursive calls
floodFill(x - 1, y, oldChar, newChar);
floodFill(x +1, y, oldChar, newChar);
floodFill( x, y-1, oldChar, newChar);
floodFill(x, y+1, oldChar, newChar);
}
public static void getNumOfRooms(String map[][]){
roomCount = -1;
for(x = 0; x < map.length; x++){
for (y = 0; y < map[0].length; y++){
if (map[x][y] == null){
floodFill(x, y, null, "x");
roomCount+=1;
System.out.println(map);
}
}
}
答案 0 :(得分:0)
懒得尝试你的代码,但这里有些东西(评论中已经提到了一些东西):
您在map[][]
检查递归调用时缺少
是的,你得到了这个:
if (x < 0 || y < 0 || x > map.length || y > map[0].length ) return;
但这并不好(甚至无用),因为您的递归调用可以访问最多+2
和-1
索引越界。也应该是>= map[0].length
。我会删除它,如果完全使用:
if (x> 0) floodFill(x-1,y, oldChar, newChar);
if (x<map .length-1) floodFill(x+1,y, oldChar, newChar);
if (y>0) floodFill(x,y-1, oldChar, newChar);
if (y<map[0].length-1) floodFill(x,y+1, oldChar, newChar);
你在填充什么阵列?
我不是JAVA编码器所以我可能错了但如果我使用 C ++ 类比那么:
public static void getNumOfRooms(String map[][])
将创建map[][]
的新本地副本,以便您访问内部的本地副本(除非它表示指针不是数组副本)。因此,您可能正在检查本地副本中的值,但洪水填充正在访问原始地图:
public static void floodFill(int x, int y, String oldChar, String newChar)
因此,本地map[][]
中的任何更改都不会导致您计算的是空格数而不是房间数。我会从String map[][]
标题中移除getNumOfRooms
操作数以解决此问题。
您忘记了背景
大多数房间布局都有外边框空间,不属于任何房间。因此,您应该扫描地图中最外面的矩形,如果找到任何空间,请在计数室之前用墙角或临时字符填充它,以避免将其计为空间。您将计数器设置为-1
而不是错误(如果没有外部空间,则应该是0
。
使用null
字符
在某些情况下,在字符串中使用null
字符可能很危险,因为某些字符串操作将其用作字符串终止符。不确定您的 JAVA string
是否也是如此,但如果是,例如在第一个地图行中通常是外部空格,那么该行可以以null
开头对于某些破坏地图布局的操作,将map[0].length
更改为零。我会使用ASCII空格而不是更安全,而且打印
map
则更容易。