2012-10-02 52 views
2

我無法弄清楚爲什麼一個完全無關的變量在每次運行遞歸算法後都被改變。我絕對沒有任何地方可以給這個變量賦新值,但是遞歸方法仍然運行並且變量被改變了。變量神祕地不斷變化遞歸算法

我寫的程序是玩連接四。它具有存儲玩家籌碼的「棋盤」對象,以及評估該玩家可以獲得多少可能連線併爲該配置指定分數的方法。

設計遞歸算法來尋找最佳芯片序列。它製作了一個董事會的副本。將芯片添加到幾個可能的位置之一(因此遞歸)。和遞歸。一旦達到基本情況,它就會發現芯片的假設配置會得到的'分數'。當它退出算法時,它會選擇提供點數的路徑。

問題是,董事會的原始副本不斷被覆蓋?該程序是這樣的。 (廣義)

int[] FindBestPath(Board OrginalBoard, int Depth) 
{ 
    Board TempBoard = OriginalBoard; 
    if(Depth > 0) 
    for(x of many possible modifications) 
    { 
     Tempboard.MakeModification(x); 
     Depth--; 
     Score = FindBestPath(TempBoard, Depth); 
     if(Score > highestScoreYet) 
     { 
      highestScoreYet = Score; 
      BestModification = x; 
     } 
    } 
    else if(Depth == 0) 
    Return new int[2] {ConfigurationScore(TempBoard), -1}; 

    return new int[2] {HighestScoreYet, BestModification}; 
} 

爲什麼會出現「原單局」,我經過時,我實際調用所有可能的方式遞歸算法GET修改「X」?我沒有添加'ref'語句或任何其他內容,因此不應保留原始內容?

是否有一些關於對象行爲和遞歸算法的奇怪現象?在Microsoft C#Express 2010中,我可以在原始板對象被修改的當前未知時刻以某種方式斷點嗎?

謝謝。

回答

1

這裏的罪魁禍首是Board是一個類,一個引用類型。當你這樣做:

Board TempBoard = OriginalBoard; 

你沒有得到董事會的副本。你可以參考同一塊電路板。

解決方案是讓Board爲一個值類型的結構或克隆板。由於使用結構爲您的情況是最有可能是一個壞主意,你應該考慮implenting一個Clone方法,並代替:

Board TempBoard = OriginalBoard; 

做:

Board TempBoard = OriginalBoard.Clone(); 
+0

實施ICloneable被認爲是不好的做法。 http://blogs.msdn.com/b/brada/archive/2003/04/09/49935。ASPX。我可能會建議使用「複製構造函數」來解決這個問題。 – Grozz

+0

你也應該使用'Clone'方法鍵入cast,因爲沒有'ICloneable'' – Grozz

+0

@Grozz首先你告訴我不要使用'ICloneable',然後你告訴我投射,如果沒有'ICloneable', 。接下來是什麼? :) –

3

如果Boardclass然後Board TempBoard = OriginalBoard;是在C#中的引用分配不像在C++中它是一個賦值,這就是爲什麼當你調用Tempboard.MakeModification(x);你有原來的改變。

考慮使用struct,它的行爲與分配時的C++類相似,或者創建一個新的臨時對象。

0

正在製作的TempBoard等於OriginalBoard這意味着他們擁有相同的參考。你可以用你想到C中的指針的方式來思考它。所以你在TempBoard中改變的任何東西都會在OriginalBoard中改變,因爲它們都指向相同的東西。結構是值類型,類是引用類型,這意味着如果你以相同的方式傳遞一個結構體,它不會像這個對象那樣改變。