【问题标题】:Filling a list with arrays, all arrays in the list are the same (in recursive function)用数组填充列表,列表中的所有数组都是相同的(在递归函数中)
【发布时间】:2023-02-13 20:22:15
【问题描述】:

我希望下面的代码用一些随机整数数组填充“outputList”列表。 事实证明它没有。当我在控制台上输出列表时,“outputList”列表中的每个数组都有相同的数字。

任何想法为什么这个列表充满了相同的数组?

随机值只是为了表明输出始终相同。我知道有一些更好的方法可以用随机值填充列表。

代码:

    List<int[]> outputList = new();
    private static void Main()
    {
        Program program = new();
        program.StartTest();  //start non-static StartTest()-method
    }

    private void StartTest()
    {
        int[] inputArray = new int[3];   //create array {0, 0, 0}

        Test(inputArray, 10);   //call Test()-method, repeat 10 times

        for(int i = 0; i < outputList.Count; i++)  //finally print the "outputList"
        {
            string outputStr = string.Join(" ", outputList[i]);
            Console.WriteLine(outputStr);
        }
        Console.ReadLine();
    }

    private void Test(int[] array, int n)
    {
        outputList.Add(array);   //add the array to the outputList

        //fill array with random integers
        Random rand = new();
        for(int i = 0; i < array.Length; i++)
           array[rand.Next(0, array.Length)] = rand.Next(0, 1000);

        //call function again, if n > 0
        n--;
        if (n > 0)
            Test(array, n);
    }

预期产出

23 432 437

43 645 902

342 548 132

...(随机值)

实际产量

252 612 761

252 612 761

252 612 761

...(总是相同的值)

我是 stackoverflow 的新手,所以请原谅我可能犯的任何低级错误。

【问题讨论】:

  • 您总是将相同的数组添加到列表中。因此,通过列表中的所有引用可以看到对数组的更改。您需要在该点创建数组的副本。您对 Test 的递归调用可能应该复制一份。
  • 大概只是完全删除给Test 方法的数组并在Test 中创建一个新数组。测试不使用给定的数组的包含。

标签: c#


【解决方案1】:

问题是你正在传递一个引用同一个数组在测试方法的每次迭代中。当您在方法内修改数组时,更改会反映在对同一数组的所有引用中。

您应该为每次迭代创建一个新数组。此外,在每次迭代中填充随机索引也是低效的,因为您可以多次在某些索引中设置值,而其他索引永远不会设置。

private void Test(int arraySize, int iterationsCount)
{
    var arr = new int[arraySize];
    outputList.Add(arr);  

    Random rand = new();
    for(int i = 0; i < arraySize; i++)
       arr[i] = rand.Next(0, 1000);

    n--;
    if (n > 0)
        Test(arraySize, iterationsCount);
}

一个理论时刻。引用类型的集合不存储 这些类型的对象。它只存储对这些对象的引用。 这就是为什么列表的 10 个值可能包含相同的原因 reference - 创建的唯一数组的地址。并访问任何 列表的索引将是同一对象对同一对象的访问 参考。

【讨论】:

    【解决方案2】:

    您的代码有几个问题。

    1. 最大的一个 - 您正在修改和添加数组的相同实例(这是一个引用类型)列表。一种方法是将数组的长度传递给 Test 方法并在那里新建它:
       void StartTest()
      {
          Test(3 , 10);   //call Test()-method, repeat 10 times
          // ...
      }
      
       void Test(int arrLength, int iterations)
       {
          var array = new int[arrLength];
          outputList.Add(array);   //add the array to the outputList
          
          //...
      
          //call function again, if iterations > 0
          iterations--;
          if (iterations > 0)
              Test(arrLength, iterations);
      }
      

      阅读更多:

      1. 以下代码:
      for(int i = 0; i < array.Length; i++)
         array[rand.Next(0, array.Length)] = rand.Next(0, 1000);
      

      不完全对应于生成“随机整数数组”的所需任务。它将填充数组的一些随机索引,不一定是所有索引,这在使用相同数组时“有效”,但在为每次迭代新创建数组时可能导致很多零。最好将其更改为:

      for(int i = 0; i < array.Length; i++)
         array[i] = rand.Next(0, 1000);
      

      附言

      此外,我将从 Test 的递归方法切换到简单的迭代方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多