2

再帰アルゴリズムを実行するたびに、まったく無関係な変数が変更される理由がわかりません。この変数に新しい値を割り当てる場所は絶対にありませんが、それでも再帰メソッドが実行され、変数が変更されます。

私が書いたプログラムは、コネクト フォーを再生しています。プレーヤーのチップがどこにあるかを保存する「ボード」オブジェクトと、その人が獲得できるコネクト フォーの数を評価し、その構成にスコアを割り当てるメソッドがあります。

再帰アルゴリズムは、チップの最適なシーケンスを見つけるように設計されています。ボードのコピーを作成します。いくつかの可能な場所の 1 つにチップを追加します (したがって、再帰)。そして再帰。ベースケースに到達すると、チップの仮想構成が受け取る「スコア」が見つかります。アルゴリズムから戻ると、最大数のポイントを与えるパスが選択されます。

問題は、ボードの元のコピーが上書きされ続けることですか? プログラムはこんな感じです。(一般化)

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};
}

再帰アルゴリズムを実際に呼び出したときに渡す「元のボード」が、考えられるすべての方法で変更「x」を取得するのはなぜですか? 「ref」ステートメントなどを追加しなかったので、元のファイルを保存する必要はありませんか?

オブジェクトの動作と再帰アルゴリズムについて既知の奇妙さはありますか? Microsoft C# Express 2010 で、元のボード オブジェクトが変更された現在不明な時点でブレークポイントを設定できますか?

ありがとうございました。

4

3 に答える 3

3

If Boardis a classthenBoard TempBoard = OriginalBoard;は、値の代入である C++ とは異なり、C# の参照代入です。そのため、呼び出すTempboard.MakeModification(x);ときに元の代入が変更されます。

struct代入で C++ クラスのように動作する whichを使用するか、新しい一時オブジェクトを作成することを検討してください。

于 2012-10-02T00:21:07.073 に答える
1

ここでの犯人Boardは、クラス、参照型です。あなたがするとき:

Board TempBoard = OriginalBoard;

ボードのコピーは入手できません。同じボードへの参照を取得します。

解決策はBoard、値型である構造体を作成するか、ボードを複製することです。あなたの状況で構造体を使用することはおそらく悪い考えであるため、Cloneメソッドを実装することを検討する必要があります。

Board TempBoard = OriginalBoard;

行う:

Board TempBoard = OriginalBoard.Clone();
于 2012-10-02T00:23:21.537 に答える
0

TempBoard を OriginalBoard と等しくしています。これは、それらが同じ参照を保持していることを意味します。C のポインターと同じように考えることができます。つまり、TempBoard で変更したものはすべて、OriginalBoard でも変更されます。どちらも同じものを参照しているためです。構造体は値型であり、クラスは参照型です。つまり、同じ方法で構造体を渡した場合、このオブジェクトのように変更されません。

于 2012-10-02T00:23:39.573 に答える