执行paintFill函数

时间:2015-02-04 22:12:15

标签: java algorithm

我对McDowell下面的代码提出了几个问题来实现paintFill函数(类似于图像编辑程序)。

1-为什么我们使用排序屏幕[y] [x]而不是屏幕[x] [y]?作者说这是图形问题的特征,但为什么呢?

2-作者将这种方法与深度优先方法进行了比较,并表示它可以非常快速地溢出堆栈。另一种方法是实现广度优先搜索的变体。它不是一个bfs方法吗?因为对于每个像素,我们首先为相邻像素着色,然后向外看它们?如果没有,bfs方法的想法是什么,为什么它也不会溢出呢?

  enum Color{
    Black, White, Red, Yellow, Green
  }

  boolean paintFill(Color[][] screen, int x, int y, Color ocolor, Color ncolor){
    if (x < 0 || x >= screen[0].length||
            y < 0 || y >= screen.length){
      return false;
    }

    if (screen[y][x] == ocolor){
      screen[y][x] = ncolor;
      paintFill(screen, x-1, y, ocolor, ncolor);
      paintFill(screen, x+1, y, ocolor, ncolor);
      paintFill(screen, x, y-1, ocolor, ncolor);
      paintFill(screen, x, y+1, ocolor, ncolor);
    }
    return true;
  }

  boolean paintFill(Color[][] screen, int x, int y, Color ncolor){
    if (screen[y][x] == ncolor){
      return false;
    }
    return paintFill(screen, x, y, screen[y][x], ncolor);
  }

2 个答案:

答案 0 :(得分:1)

  
    

1-为什么我们使用排序屏幕[y] [x]而不是屏幕[x] [y]?作者说这是图形问题的特征,但为什么呢?

  

我猜y代表垂直轴上的位置。在这种情况下,您不能使用screen[x][y],因为第一个维度是与垂直轴相关的维度。因此,必须使用y索引。

  
    

2-作者将这种方法与深度优先方法进行了比较,并表示它可以非常快速地溢出堆栈。另一种方法是实现广度优先搜索的变体。这不是一个bfs方法吗?因为对于每个像素,我们首先为相邻像素着色,然后向外看它们?如果没有,bfs方法的想法是什么,为什么它也不会溢出呢?

  

它不是BFS,因为您的调用是递归深度优先调用。这意味着你没有为所有相邻的像素着色,你通过递归调用为一个像素(在你的情况下是左边的一个)着色:

paintFill(screen, x-1, y, ocolor, ncolor);

然后你为这个左边的邻居上色(由于同一种递归调用),然后是那个左边的邻居,依此类推,直到你到达屏幕边缘没有左边邻居的像素。然后你回溯到你着色的最后一个像素,并从那里做第二次递归调用:

paintFill(screen, x+1, y, ocolor, ncolor);

着色右邻居(自从你来自右边后可能已经着色,所以在这种情况下这将快速返回)。这种情况一直持续到所有事情都被着色为止。

正如你所看到的,它首先是深度,因为你向某个方向移动,直到你出于某种原因不再向那个方向移动。对于广度优先,您必须使用FIFO队列:在队列中插入一个像素位置并为其着色。然后在队列中有元素时重复:从队列中删除第一个元素,为其邻居着色并将其邻居插入队列中。

这将避免递归调用,并且会产生类似于在地板上放下一罐油漆时所发生的效果:颜色将从一个点均匀向外扩展。

深度优先看起来类似于如果你试图在一个限制条件下给一张纸着色,你应该只改变你的手移动的方向,如果不这样做会导致你破坏纸张的边界。目前的算法是DFS。

答案 1 :(得分:1)

  1. 图像格式和屏幕设备使用水平扫描线,因此是水平线的垂直阵列。所以[y][x]。参见模拟电视信号,BMP格式。

  2. DFS的可视化将是雷击,而BFS将在培养皿中培养细菌菌落。由于任何搜索都没有指向,DFS有许多部分候选路径,它们在任何方向上卷曲,因此更长。 BFS更自然。就像你要保持生长的外轮廓一样。在另一个视图中:BFS增长受外边界限制,而DFS以非常不受限制的卷曲路径开始。这些路径较长,可能在指数上效率较低。最大路径长度B * W将是递归深度。在C中,可以定义一个小堆栈,但堆栈溢出似乎有点过头了。