C#在嵌套列表中丢失值

时间:2016-03-16 21:30:27

标签: c# list exception collections

我的嵌套列表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个项目(lol)..现在问题是它还将这个确切的1项添加到minMinatRed嵌套列表中的每个列表中,即所有100万个列表的长度为1,并且其中只有1个重复变量。这就是我能找到的关于当前问题的内容,但是我不知道为什么会发生这种情况或者我该如何解决它。我还阅读了Mystical所写的一些问题和答案,他也是StackOverFlow用户。在他们讨论分支预测的地方,我不确定这是不是我的情况,但它可能是相关的。欢迎任何建议和解释。英语不是我的母语..

更新1 忘记包含minataKolonaminatRed&amp;&amp;的初始化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;
    }

2 个答案:

答案 0 :(得分:5)

问题是List<T>是一种引用类型,因此,当您将列表minatRedminataKolona分别添加到minMinatRedminMinataKolona时, “我没有创建一个新的(克隆的)列表。

minMinatRedminMinataKolona)中的所有列表都指向同一个列表:minatRedminataKolona),因此当您清除minatRed(或{{ 1}}),minataKolona(或minMinatRed)中的所有列表也被清除,因为实际上是相同的列表。

您可以在minMinataKolona循环中解决此声明minatRedminataKolona

for

当然你不能清空这些清单:

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

答案 1 :(得分:0)

我同意阿图罗。通常,代码看起来像下面的代码。我无法从您的代码中告诉我们有哪些等同于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);
                 }
             }