【问题标题】:C# Losing values in a nested ListC# 在嵌套列表中丢失值
【发布时间】:2016-03-16 21:30:27
【问题描述】:

我的 int 嵌套列表 (List<List<int>>) 遇到了一个非常奇怪的问题。在我将超过 100 万个列表放入其中之后的某个时刻,它们都失去了它们的值,即它们中有 0 个元素.. 真的很奇怪,对吧?我怀疑我在里面放了太多的清单。但是我放了一个 if 语句来检查嵌套列表的长度是否正好是 100 万,并在其中添加了一个断点。最终,超出嵌套列表功能的情况并非如此,这完全让我头疼。我将在这里发布代码,以便我可以尝试解释

        //it will iterate 8^8 times - 16.7 million times
        private static List<List<int>> minMinatRed = new List<List<int>>();
        private static List<List<int>> minMinataKolona = new List<List<int>>();
        var tempHodove = new List<Tuple<bool, int[]>>();
        int novMinatRed = red;
        int novaMinataKolona = kolona;
        for (int i = 0; i < numberOfVariations; i++)
        {
            tempHodove.Clear();
            var hodove = UpdateList(novMinatRed, novaMinataKolona);
            int x = i;
            for (int j = 0; j < size; ++j)
            {
                result[j] = tempArr[x % size];
                x /= size;
            }
            for (int k = result.Length - 1; k >= 0; k--)
            {
                tempHodove.Add(hodove[result[k]]);
            }
            bool trueValue = tempHodove.Any(c => c.Item1);
            while (trueValue)
            {
                foreach (var hod in tempHodove.Where(hod => hod.Item1))
                {
                    novMinatRed += hod.Item2[0];
                    novaMinataKolona += hod.Item2[1];
                    minatRed.Add(novMinatRed);
                    minataKolona.Add(novaMinataKolona);
                    count++;
                    break;
                }
                if (novMinatRed == kraenRed && novaMinataKolona == krainaKolona)
                {
                    if (minCount > count)
                    {
                        minCount = count;
                    }
                    minMinatRed.Add(minatRed);
                    minMinataKolona.Add(minataKolona);
                }
                hodove = UpdateList(novMinatRed, novaMinataKolona);
                tempHodove.Clear();
                for (int k = result.Length - 1; k >= 0; k--)
                {
                    tempHodove.Add(hodove[result[k]]);
                }
                trueValue = tempHodove.Any(c => c.Item1);
            }
            if (minMinatRed.Count == 1000000)
            {

            }
            minataKolona.Clear();
            minatRed.Clear();
            count = 0;
            novMinatRed = nachalenRed;
            novaMinataKolona = nachalnaKolona;
        }

问题出在minMinatRedminMinataKolona 列表中,正如您所见,我只在其中添加了一些值:

if (novMinatRed == kraenRed && novaMinataKolona == krainaKolona)
{
     if (minCount > count)
     {
          minCount = count;
     }
     minMinatRed.Add(minatRed); //here
     minMinataKolona.Add(minataKolona); //and here
}

好吧,一旦断点在 :

中触发
if (minMinatRed.Count == 1000000){ }

我开始检查发生了什么。我发现一旦代码到达这一点:

minataKolona.Clear();
minatRed.Clear();

它不仅会擦除 minatRed 值,还会擦除 minMinatRed 值,minataKolonaminMinataKolona 也是如此。 此外,一旦它返回循环并向minatRedminataKolona 添加一些值,它也会在嵌套列表中更具体地添加相同的值:

foreach (var hod in tempHodove.Where(hod => hod.Item1))
{
     novMinatRed += hod.Item2[0];
     novaMinataKolona += hod.Item2[1];
     minatRed.Add(novMinatRed);  //here
     minataKolona.Add(novaMinataKolona);  //and here
     count++;
     break;
}

现在,由于我们之前从 minatRed 中擦除了所有值,因此它显然没有任何内容,一旦我们向其中添加 1 个项目,它就有 1 个项目(哈哈).. 现在问题是它还添加了这个确切的 1 项进入 minMinatRed 嵌套列表中的每一个列表中,即所有 100 万个列表的长度为 1,并且其中只有 1 个重复变量。这就是我能够找到的关于当前问题的信息,但是我不知道为什么会发生这种情况或如何解决它。我还阅读了由 StackOverFlow 用户 Mystical 撰写的一些问答。在他们讨论分支预测的地方,我不确定这是否是我的情况,但它可能是相关的。欢迎任何建议和解释。英语不是我的母语..

更新 1 忘记包含 minataKolonaminatRed && numberOfVariations 的初始化

    private static readonly List<int> minatRed = new List<int>();
    private static readonly List<int> minataKolona = new List<int>();
    private static readonly double numberOfVariations = Math.Pow(size, size);

更新 2 包含 UpdateList 方法

 private static List<Tuple<bool, int[]>> UpdateList(int red, int kolona)
    {
        var vsichkiHodove = new List<Tuple<bool, int[]>>()
        {
            new Tuple<bool, int[]>(Nadqsno(red, 1) && Napred(kolona, 2), new[]
            {
                +1,
                +2
            }),
            new Tuple<bool, int[]>(Nadqsno(red, 2) && Napred(kolona, 1), new[]
            {
                +2,
                +1
            }),
            new Tuple<bool, int[]>(Nalqvo(red, 1) && Napred(kolona, 2), new[]
            {
                -1,
                +2
            }),
            new Tuple<bool, int[]>(Nalqvo(red, 2) && Napred(kolona, 1), new[]
            {
                -2,
                +1
            }),
            new Tuple<bool, int[]>(Nadqsno(red, 2) && Nazad(kolona, 1), new[]
            {
                +2,
                -1
            }),
            new Tuple<bool, int[]>(Nalqvo(red, 2) && Nazad(kolona, 1), new[]
            {
                -2,
                -1
            }),
            new Tuple<bool, int[]>(Nadqsno(red, 1) && Nazad(kolona, 2), new[]
            {
                +1,
                -2
            }),
            new Tuple<bool, int[]>(Nalqvo(red, 1) && Nazad(kolona, 2), new[]
            {
                -1,
                -2
            }),
        };
        return vsichkiHodove;
    }

【问题讨论】:

  • 您是否使用 int 来索引一个非常大的数组。请改用 long。
  • 它将迭代 8^8 次 - 167 万次,因此对于 int 来说应该不是问题
  • 您是否显示所有相关代码?我没有看到 minataKolona 分配在哪里。
  • 不挑剔,但 8^8 是 16777216
  • 正确,int仍然不是问题

标签: c# list exception collections


【解决方案1】:

问题是 List&lt;T&gt; 是一个引用类型,因此,当您将列表 minatRedminataKolona 分别添加到 minMinatRedminMinataKolona 时,您并没有创建新的(克隆的)列表.

minMinatRedminMinataKolona)中的所有列表都指向同一个:minatRedminataKolona),所以当你清除minatRed(或minataKolona)时,minMinatRed中的所有列表(或minMinataKolona) 也被清除,因为实际上是同一个列表。

您可以在 for 循环内声明 minatRedminataKolona 来解决这个问题:

for (int i = 0; i < numberOfVariations; i++)
{
    var minatRed = new List<int>();
    var minataKolona = new List<int>();
    ...

当然你不能清空列表:

//minataKolona.Clear();  Comment this lines or just remove it
//minatRed.Clear();      Comment this lines or just remove it

【讨论】:

    【解决方案2】:

    我同意阿图罗的观点。通常代码看起来像下面的代码。我无法从您的代码中看出与 newRow (novMinatRed) 等效的位置正在被清除。

                List<List<int>> minMinatRed = new List<List<int>>();
                 for (int i = 0; i < 10; i++)
                 {
                     List<int> newRow = new List<int>();
                     minMinatRed.Add(newRow);
                     for (int j = 0; j < 10; j++)
                     {
                         newRow.Add(j);
                     }
                 }
    

    【讨论】:

      猜你喜欢
      • 2023-04-05
      • 2020-05-25
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 2016-04-19
      • 2017-06-17
      • 2015-03-07
      • 2018-10-15
      相关资源
      最近更新 更多