全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4003
推到 Plurk!
推到 Facebook!

使用遞迴的問題

答題得分者是:TheMoon
YTAI
一般會員


發表:2
回覆:1
積分:0
註冊:2004-09-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-15 10:15:06 IP:210.68.xxx.xxx 未訂閱
請問大家:我參考站上的文章後,寫的程式碼如下
 
void __fastcall TForm1::RzBitBtn4Click(TObject *Sender)
{
   Image2->Picture = NULL;
   Memo1->Clear();
   Byte *ptr = NULL;
   Graphics::TBitmap *PIC = new Graphics::TBitmap();
   PIC->Assign(Image1->Picture);
   PIC->PixelFormat = pf24bit;
   Image2->Canvas->Brush->Style = bsClear;
   Image2->Canvas->Pen->Color = clAqua;
   for (int y=1; yHeight-1; y++)
   {
      ptr = (Byte*)PIC->ScanLine[y];
      for (int x=1; xWidth-1; x++)
      {
         if (ptr[x*3] == 255)
         {
            CCL(PIC, x, y);
         }
      }
   }
   delete PIC;
}    void __fastcall TForm1::CCL(Graphics::TBitmap *BMP, int x, int y)
{
   SetPixel(BMP->Canvas->Handle, x, y, clBlack);
   Image2->Canvas->Pixels[x][y] = clBlue;
   Memo1->Lines->Add("X:"+IntToStr(x)+" Y: "+IntToStr(y));
   Application->ProcessMessages();
   if (BMP->Canvas->Pixels[x+1][y]==clWhite)
      CCL(BMP, x+1, y);       if (BMP->Canvas->Pixels[x][y+1]==clWhite)
      CCL(BMP, x, y+1);       if (BMP->Canvas->Pixels[x-1][y]==clWhite)
      CCL(BMP, x-1, y);       if (BMP->Canvas->Pixels[x][y-1]==clWhite)
      CCL(BMP, x, y-1);
}
測試圖片如下所示 小弟不懂地方是如下的數據
    X:41 Y: 40
X:42 Y: 40
X:43 Y: 40
X:44 Y: 40
X:45 Y: 40
X:46 Y: 40
X:47 Y: 40
X:39 Y: 41  <---為什麼能跳到這個位置?  
X:39 Y: 42
X:39 Y: 43
....
希望前輩能幫我解惑
TheMoon
中階會員


發表:17
回覆:95
積分:67
註冊:2002-06-05

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-15 14:38:10 IP:202.39.xxx.xxx 未訂閱
給個建議, 請善用Add Watch和設定中斷點來trace程式, 如此便能清楚地知道遞迴是如何呼叫和展開的, 底下的說明希望你能瞭解。 < class="code"> void __fastcall TForm1::RzBitBtn4Click(TObject *Sender) { Image2->Picture = NULL; Memo1->Clear(); Byte *ptr = NULL; Graphics::TBitmap *PIC = new Graphics::TBitmap(); PIC->Assign(Image1->Picture); PIC->PixelFormat = pf24bit; Image2->Canvas->Brush->Style = bsClear; Image2->Canvas->Pen->Color = clAqua; for (int y=1; yHeight-1; y ) { ptr = (Byte*)PIC->ScanLine[y]; //這裡的用意是在搜尋第一個白點 for (int x=1; xWidth-1; x ) { if (ptr[x*3] == 255) { CCL(PIC, x, y); //當x=27 y=40時,開始呼叫CCL function } } } delete PIC; } //整段程式碼的重點是在CCL這個function,裡面有用到遞迴呼叫。 void __fastcall TForm1::CCL(Graphics::TBitmap *BMP, int x, int y) { //在原圖上將白點設為黑點,表示此點已經走過 SetPixel(BMP->Canvas->Handle, x, y, clBlack); //在Image2上對應的位置塗上藍點 Image2->Canvas->Pixels[x][y] = clBlue; //在Memo1秀出(X,Y)位置 Memo1->Lines->Add("X:" IntToStr(x) " Y: " IntToStr(y)); Application->ProcessMessages(); //下面是遞迴呼叫程式的判斷條件 //當遇到白點就呼叫CCL function //要注意呼叫CCL function的程式碼位置及x,y的值 //因為程式呼叫展開到某一層執行完畢後會再跳回上一層的進入位置 if (BMP->Canvas->Pixels[x 1][y]==clWhite) //向右走 CCL(BMP, x 1, y); //x=27 1 y=40, 呼叫CCL function //因為當x=27..46 y=40時,向右一直都有白點, //所以都會執行到上面這個if判斷式裡的CCL,直到x=47 y=40。 //當x=47 y=40時,發現向下,向左,向上都是黑點,於是CCL function執行完畢, //跳回上一層x=46 y=40時的程式執行位置,並繼續執行以下的程式。 //因為一直碰到黑點,所以會一直跳回上一層呼叫處,直到x=39 y=40。 if (BMP->Canvas->Pixels[x][y 1]==clWhite) //向下走 CCL(BMP, x, y 1); if (BMP->Canvas->Pixels[x-1][y]==clWhite) //向左走 CCL(BMP, x-1, y); if (BMP->Canvas->Pixels[x][y-1]==clWhite) //向上走 CCL(BMP, x, y-1); }
YTAI
一般會員


發表:2
回覆:1
積分:0
註冊:2004-09-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-15 15:21:16 IP:210.68.xxx.xxx 未訂閱
謝謝TheMoon前輩的指導,我了解了 原來關鍵字在這一句
引言: 因為程式呼叫展開到某一層執行完畢後會再跳回上一層的進入位置 所以會一直跳回上一層呼叫處,直到x=39 y=40。
還有小一個地方想請教TheMoon前輩,您說[Add Watch]指的是? 因為後來我是用View→Debug Windows→Call Stack才看出程式流程的 再次感謝TheMoon
TheMoon
中階會員


發表:17
回覆:95
積分:67
註冊:2002-06-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-15 15:38:44 IP:202.39.xxx.xxx 未訂閱
引言: 謝謝TheMoon前輩的指導,我了解了 原來關鍵字在這一句
引言: 因為程式呼叫展開到某一層執行完畢後會再跳回上一層的進入位置 所以會一直跳回上一層呼叫處,直到x=39 y=40。
還有小一個地方想請教TheMoon前輩,您說[Add Watch]指的是? 因為後來我是用View→Debug Windows→Call Stack才看出程式流程的 再次感謝TheMoon < face="Verdana, Arial, Helvetica"> 是在Run→Add Watch裡, 點選後會出現Watch List視窗, 你可以設定想要觀察的變數或物件
系統時間:2024-04-28 12:26:22
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!