Question

A 2D array represent an image, each pixel has a color, this recursive function job is to transform a region of the same color (c) surrounding pixel (x,y) to a new color (newC).The function is working fine until i pass a large number like x=200, y=200 and a SO occurs. How can i handle this case? or if there is a better solution other than recursion?

void Region(int x, int y, char newC, char c) { //c is current color, newC is new Color
    if(c == newC) return;
    arr[y][x]=newC;
    if(arr[y][x-1 ]== c && x-1 > 0) Region(x-1, y, newC, c);
    if(arr[y-1][x] == c && y-1 > 0) Region(x, y-1, newC, c);
    if(arr[y][x+1] == c && x+1 <= M) Region(x+1, y, newC, c);
    if(arr[y+1][x] == c && y+1 <= N) Region(x, y+1, newC, c);
}

Example of 2 regions (Os & Vs):

OOOOOO
OOVOOO
OVVVOO
OVVOOO
OVOOOO

Was it helpful?

Solution

As in the link there was a more efficient solution than the recursion

http://en.wikipedia.org/wiki/Flood_fill

Flood-fill (node, target-color, replacement-color):

1. If target-color is equal to replacement-color, return.
2. Set Q to the empty queue.
3. Add node to the end of Q.
4. While Q is not empty: 
5.     Set n equal to the last element of Q.
6.     Remove last element from Q.
7.     If the color of n is equal to target-color:
8.         Set the color of n to replacement-color.
9.         Add west node to end of Q.
10.        Add east node to end of Q.
11.        Add north node to end of Q.
12.        Add south node to end of Q.
13. Return.

This is my first attempt at transforming the pseudo code to C++:

std::deque<char> myqueue;
void Region(int x,int y,char newC,char c)
{
    char n;
    if(c==newC)return;
    myqueue.empty();
    myqueue.push_back(arr[y][x]);
    while (myqueue.size()!=0)
    {
        n=myqueue.back();
        myqueue.pop_back();
        if(n==c)
        {
            n=newC;
            if(x-1>0)    myqueue.push_back(arr[y][x-1]);
            if(y-1>0)    myqueue.push_back(arr[y-1][x]);
            if(x+1<=M)   myqueue.push_back(arr[y][x+1]);
            if(y+1<=N)   myqueue.push_back(arr[y+1][x]);
        }
    }
}

OTHER TIPS

Since your changing the entire thing into ONE color, why don't you just use 2 nested for loops, then you won't have to do your if statement checks, therefore your function won't be recursive.

Try this:

for(int i = 0; i < y; i++){
  for(int j = 0; j < x; j++){
      arr[i][j] = newC;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top