洪水填充算法计算房间

时间:2016-05-07 15:36:17

标签: java algorithm dictionary multidimensional-array flood-fill

我正在尝试制作一个洪水填充算法,该算法计算墙壁所包围的空白空间的数量。 我使用的是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);
             }
     }
 }

1 个答案:

答案 0 :(得分:0)

懒得尝试你的代码,但这里有些东西(评论中已经提到了一些东西):

  1. 您在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);
    
  2. 你在填充什么阵列?

    我不是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操作数以解决此问题。

  3. 您忘记了背景

    大多数房间布局都有外边框空间,不属于任何房间。因此,您应该扫描地图中最外面的矩形,如果找到任何空间,请在计数室之前用墙角或临时字符填充它,以避免将其计为空间。您将计数器设置为-1而不是错误(如果没有外部空间,则应该是0

  4. 使用null字符

    在某些情况下,在字符串中使用null字符可能很危险,因为某些字符串操作将其用作字符串终止符。不确定您的 JAVA string是否也是如此,但如果是,例如在第一个地图行中通常是外部空格,那么该行可以以null开头对于某些破坏地图布局的操作,将map[0].length更改为零。我会使用ASCII空格而不是更安全,而且打印map则更容易。