2017-05-08 19 views
2

マトリクスで部屋面積を計算するタスクがあります。最初の入力は行と列の座標です - ゼロは空きスペース、1 - は壁です。問題は、flood fill関数が私にスタックオーバーフローの例外を与えることです。フラッドフィルアルゴリズム - Room Area

#include<iostream> 
#include<conio.h> 
using namespace std; 

int a[5][5] = { {0,0,1,0,0}, 
       {0,0,1,0,0}, 
       {0,0,1,1,1}, 
       {1,1,1,0,0}, 
       {0,0,1,0,0}, 
}; 

bool vis[5][5] = { {0,0,0,0,0}, 
        {0,0,0,0,0}, 
        {0,0,0,0,0}, 
        {0,0,0,0,0}, 
        {0,0,0,0,0}, 
}; 
int c = 0; 

void flood(int row, int col){ 
    if(row < 0 || row > 4 || col < 0 || col > 4) 
     return; 
    if(a[row][col] == 0 && !vis[row][col]){ 
     c++; 
     vis[row][col] = 1; 
    } 
    flood(row-1, col); 
    flood(row+1, col); 
    flood(row,col-1); 
    flood(row, col+1); 
} 

int main(){ 
    int row, column; 
    cin>>row>>column; 

    flood(row,column); 
    cout<< c; 

    getch(); 
return 0; 
} 

答えて

2

既に訪問したフィールドをヒットした場合は再発しないでください。

コードでは、!vis[row][col]句を入力すると、floodへの再帰呼び出しが防止されるはずです。 ifの中でそれらを動かすだけで達成できます(または、もう少し明確に、すべてを外に移動して条件を反転させることで)。これにより、壁に当たったときの再帰を防ぐこともできますが、それはでもです。

+0

flood-fillアルゴリズムの再帰的な降下は、一般的には非常に悪い考えです。常に1回の非常に深い再帰で領域全体を埋める傾向があるため、 'N'が画像の幅/高さ、必要なスタック空間は 'O(N^2)'です。興味深い問題のサイズに移行すると、これは非常に迅速にセグメンテーションされます。 – cmaster

+0

@ cmaster良い点。単純なキューベースの反復的なアプローチでさえもうまくいくでしょう。しかし、これは運動のように見えます。 –

+0

再帰の深さの問題は、実際にフラッド・フィルを使用する必要があるとき、私たちは必然的に遭遇します。だから、読者が根本的な問題があることに気づくのに5分かかっているのか、あるいは再帰的な洪水と再構成的な洪水の結論に至る前にsegfaultをデバッグするのに不確定な時間を加えて30分かかりますか?塗りつぶしは悪い考えです。他者の経験から学ぶことは、あなた自身の過ちをすることよりもはるかに効率的です。そういうわけで、私は通常、そのような固有の問題に対して警告を出したり、警告を受け取ったりすることを好みます。 – cmaster