配列にフラッド フィルを適用する方法を知りたかったのですが、私の配列は 2 次元であり、新しいローマン フォント タイプの文字境界が含まれています。境界線には 1 が含まれ、内側と外側はすべて 0 です。内部のみを0ではなくすべて1で埋めたい。しかし、より多くのメモリを必要としないロジックが必要です。したがって、再帰とスタックまたはキューを避けてください
4 に答える
私は通常、他の人のために宿題をすることはありませんが、私は挑戦が好きでした:
int c = -1;
while (c < 0)
{
/* Store breadcrumb trail, look to carry on */
a[x][y] = c--;
if (!hunt(0))
{
/* Nowhere to go, so back-track by looking for breadcrumb */
a[x][y] = 1;
c += 2;
hunt(c);
}
}
bool_t hunt(int v)
{
if (a[x-1][y] == v) { x--; return TRUE; }
if (a[x+1][y] == v) { x++; return TRUE; }
if (a[x][y-1] == v) { y--; return TRUE; }
if (a[x][y+1] == v) { y++; return TRUE; }
return FALSE;
}
これは、配列の端にヒットするかどうかをチェックしないことに注意してください。また、配列要素がeg int
sであり、値0
と1
画像のみを使用していると想定しています。
あなたの仕事はあまり意味がありません。書体がある場合、塗りつぶしで塗りつぶすのではなく、代わりに塗りつぶされたポリゴンとして直接レンダリングします。確実に良い結果が得られない場合、特にセリフ フォントの場合、どの部分が書体の内外にあるかを判断します。
塗りつぶされたポリゴンの典型的な回路図アルゴリズムは次のようになり (スタックや再帰は必要ありません)、特定の条件下でビットマップにも適用できます (後で説明します)。
各行 (または列、データ構造により適したもの) について、追跡している仮想線とすべての多角形の線 (境界) の交点ごとに塗りつぶしを切り替えます。
これを仮定します (O 文字の中間行である可能性があります):
00010010001001000
^ ^ ^ ^
| | | stop
| | start
| stop
start
結果:
00011110001111000
これはビットマップでも機能しますが、実際には常に開始と停止に 2 つの境界がある場合に限ります。
function LowMemFloodFill(pixel)
FillPixel(pixel)
Do
didFill = false
For each pixel
If current pixel has been filled
For each adjacent pixel
If adjacent has not been filled
FillPixel(adjacent)
didFill = true
End
End
End
End
While didFill
End
問題は、ピクセルが塗りつぶされている (未使用の色で塗りつぶす) ことを認識できなければならないことです。また、これは非常に遅くなります。
基本的にできません。この情報をどこかに保存する必要があります。これは、現在のセクションが完了した後で、他のどこから入力を開始するかを知る必要があるためです。再帰を使用すると、暗黙的に実行できます。独自のスタックを保持することで、明示的にそれを行うことができ、おそらくいくらか節約できます。Oli Charlesworth は、画像と同じサイズの配列を保持することでかわいいことを行いますが、再帰や位置のスタックを保持するよりも多くのメモリを使用します。