Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 递归算法后,变量神秘地不断变化_C#_Recursion - Fatal编程技术网

C# 递归算法后,变量神秘地不断变化

C# 递归算法后,变量神秘地不断变化,c#,recursion,C#,Recursion,我不明白为什么每次运行递归算法后,一个完全不相关的变量都会发生变化。在任何地方,我都不会以任何方式为这个变量分配新值,但递归方法仍然会运行,变量也会发生变化 我写的程序正在播放连接四。它有一个“board”对象,用于存储玩家芯片的位置,还有一个方法,用于评估玩家可以获得多少个可能的connect four,并为该配置分配分数 设计了递归算法来寻找最优的芯片序列。它制作了一份董事会的副本。将芯片添加到几个可能的位置之一,从而实现递归。然后再发生。一旦达到基本情况,它就会找到假设的芯片配置将获得的“

我不明白为什么每次运行递归算法后,一个完全不相关的变量都会发生变化。在任何地方,我都不会以任何方式为这个变量分配新值,但递归方法仍然会运行,变量也会发生变化

我写的程序正在播放连接四。它有一个“board”对象,用于存储玩家芯片的位置,还有一个方法,用于评估玩家可以获得多少个可能的connect four,并为该配置分配分数

设计了递归算法来寻找最优的芯片序列。它制作了一份董事会的副本。将芯片添加到几个可能的位置之一,从而实现递归。然后再发生。一旦达到基本情况,它就会找到假设的芯片配置将获得的“分数”。当它退出算法时,它会选择提供最大点数的路径

问题是电路板的原始副本不断被覆盖?节目是这样的。广义的

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中,当原始board对象被修改时,我是否可以在当前未知的时刻设置断点

谢谢。

如果Board是一个类,那么Board TempBoard=原始板;C中的引用赋值不同于C++,它是赋值赋值,这就是为什么当你调用Tempboard.MakeModificationx时;你把原来的那个换了

考虑使用赋值结构类似于C++类的赋值结构,或者创建一个新的临时对象。

< P>如果是一个类,则在TaveBase=原板上;C中的引用赋值不同于C++,它是赋值赋值,这就是为什么当你调用Tempboard.MakeModificationx时;你把原来的那个换了

考虑使用赋值结构类似于C++类的赋值结构,或者创建一个新的临时对象。

这里的罪魁祸首是,板是一个类,一个引用类型。当您这样做时:

Board TempBoard = OriginalBoard;
你没有得到董事会的副本。你得到了对同一块板的引用

解决方案是将线路板设为一个值类型的结构,或者克隆线路板。既然使用Strut作为您的情况很可能是个坏主意,那么您应该考虑使用克隆方法,而不是:

Board TempBoard = OriginalBoard;
做:

罪魁祸首是Board是一个类,一个引用类型。当您这样做时:

Board TempBoard = OriginalBoard;
你没有得到董事会的副本。你得到了对同一块板的引用

解决方案是将线路板设为一个值类型的结构,或者克隆线路板。既然使用Strut作为您的情况很可能是个坏主意,那么您应该考虑使用克隆方法,而不是:

Board TempBoard = OriginalBoard;
做:


您正在使临时板与原始板相等,这意味着它们具有相同的引用。你可以用C中指针的同样方式来考虑它,所以你在TempBoard中改变的任何东西都会在OriginalBoard中改变,因为它们都指向相同的东西。结构是值类型,类是引用类型,这意味着如果以相同的方式传递结构,它不会像此对象那样更改。

您正在使临时板等于原始板,这意味着它们具有相同的引用。你可以用C中指针的同样方式来考虑它,所以你在TempBoard中改变的任何东西都会在OriginalBoard中改变,因为它们都指向相同的东西。结构是值类型,类是引用类型,这意味着如果以相同的方式传递结构,它不会像此对象那样更改。

实现IClonable被认为是一种不好的做法。我可能会建议使用复制构造函数来处理这个问题。您还应该键入cast from Clone方法,因为没有ICloneable@Grozz首先你告诉我不要使用iClonable,然后你告诉我使用cast,如果没有iClonable,这是不需要的。下一步怎么办我可能是个白痴,但是。克隆似乎不是唯一可用的。MemberwiseClone。有什么我遗漏的吗?@MichaelMolter您需要编写自己的克隆。实现iClonable被认为是一种糟糕的做法。我可能会建议使用复制构造函数来处理这个问题。您还应该键入cast from Clone方法,因为没有ICloneable@Grozz首先你告诉我不要使用iClonable,然后你告诉我使用cast,如果没有iClonable,这是不需要的。下一步怎么办我可能是个白痴,但是。克隆似乎不是唯一可用的。MemberwiseClone。有什么我遗漏的吗?@MichaelMolter你需要写你自己的克隆人。