反復再帰的な転写記録体操

自動シード充填アルゴリズムの実装に使用切断するように設計されたもの古典的なゲームピクセルマッピングツールの。

比較的大きな画像要素のようないくつかの画像は、その後遭遇再帰的に始まり、しかし、多くの場合、C#1Mデフォルトのスレッドスタックメモリとクラッシュを実行しているときに満たされました。彼らはデータ操作の完全に正確に制御されているのスタックを作成するので、単純に反復形を変え、成功しなかった複数行の変換のさまざまなを使用してみてください。

CSコードでイベント処理の一形態である反復の後に変更されたコードのここで傍受片。わずかなツールなので、完全にインターフェースロジックから分離されません。

        //堆栈最大深度
        private const int MaxStackFrames = 640 * 480; private Stack<FillStackFrame> mStack = new Stack<FillStackFrame>(MaxStackFrames); private void fillRegion(int x, int y) { //防止多线程操作堆栈引起的问题 lock (this) { //从UI初始化本次调用不会变的参数 int distance = Convert.ToInt32(txtDistance.Text); //复位堆栈并且压入初始数据 mStack.Clear(); var frame = new FillStackFrame(); frame.x = x; frame.y = y; mStack.Push(frame); //堆栈为空即所有连接区域被填充完毕,执行结束 while (mStack.Count > 0) { //弹出堆栈数据 var popped = mStack.Pop(); x = popped.x; y = popped.y; //递归终止条件1 遇到填充区域越界 if (x < 0 || y < 0 || x >= srcImg.Width || y >= srcImg.Height) continue; //递归终止条件2 遇到背景色,或者已搜索像素 if (!isTransparent(srcImg, x, y) && tmpImg.GetPixel(x, y).A != 255) { tmpImg.SetPixel(x, y, fillColor); if (maxX < x) maxX = x; if (minX > x) minX = x; if (maxY < y) maxY = y; if (minY > y) minY = y; for (int i = 1; i <= distance; ++i) { if (mStack.Count >= MaxStackFrames) throw new StackOverflowException("填充蒙版时堆栈溢出!"); //八个方向延伸搜索,这里的所有堆栈Push操作换回FillRegion方法的调用,就是原本的递归写法了 mStack.Push(new FillStackFrame() { x = x - i, y = y}); mStack.Push(new FillStackFrame() { x = x + i, y = y}); mStack.Push(new FillStackFrame() { x = x, y = y - i}); mStack.Push(new FillStackFrame() { x = x, y = y + i}); mStack.Push(new FillStackFrame() { x = x - i, y = y - i}); mStack.Push(new FillStackFrame() { x = x + i, y = y + i}); mStack.Push(new FillStackFrame() { x = x - i, y = y + i}); mStack.Push(new FillStackFrame() { x = x + i, y = y - i}); } } } } }

再帰的手続きのターンの繰り返しを要約したものです。

  1. クラスで使用される元メンバ変数と定数の初期化関数の呼び出しは、クラスのメンバ変数や定数を直接初期化することができます。
  2. 反復ループに入る前に配置され、一定の距離が距離を延ばす場合、このコールで初期化データ、。
  3. 再帰関数のパラメータ型フレームの合成、代わりに、実行時のスタックメモリが提供するスタック<フレーム>を作成します。ケースは、クラス変数のメンバとすることができるようにスタックは、ローカル変数の関数であってもよいです。
  4. 着信フレームのパラメータの初期圧入
  5. 反復ループ、ループの繰り返しに、基本的な身体機能の再帰的な実装が再成形していたです。
  6. 反復ループのすべての機能は、再帰的に新しい建物のフレーミングパラメータに置き換えると、スタックに押し込ま自身を呼び出します。
  7. ループの本来の復帰の繰り返しに進みます。
  8. あなたはすべてオリジナルの再帰的なニーズの外にある場合は、反復ループでブレークを追加します。
  9. その他の動作シーケンスは変更されません。

 

おすすめ

転載: www.cnblogs.com/fancybit/p/11412216.html