如何在 C# 中消除二维数组中的重复项

刚开始学习编程,我需要没有重复的二维数组。这段代码(为 1D 编辑得很好)在 1D 上工作得很好,但在 2D 上却不行,也不知道为什么。如果有人帮助我,我会很高兴。谢谢。


        Random r = new Random();

        int[,] array = new int[10, 8];


        for (int i = 0; i < array.GetLength(0); i++)

        {

            for (int j = 0; j < array.GetLength(1); j++)

            {

                array[i, j] = r.Next(10, 100);

                for (int k = 0; k < i; k++)

                {

                    for (int l = 0; l < j; l++)

                    {

                        if (array[i,j] == array[k,l])

                        {

                            i--;

                            j--;

                            break;

                        }

                    }

                }

            }

        }


长风秋雁
浏览 205回答 3
3回答

海绵宝宝撒

使用嵌套j循环,您将为每个填充整个第二个维度i,但在k和l循环中,您只检查当前单元格左上角的网格。您可以放置一个数字两次,因为您没有检查每个以前填充的位置。如果我们把代码改成这样:&nbsp; &nbsp; &nbsp; &nbsp; for (int k = 0; k < array.GetLength(0); k++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int l = 0; l < array.GetLength(1); l++)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (i != k && j != l && array[i, j] == array[k, l])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; j--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }然后你消除了那个问题,但你很快发现你得到了一个IndexOutOfRangeException,因为你同时递减了两个i& j。这并没有将您移动到以前的值 - 它跳回一整行并留下一个单元格 - 最终发送i或发送j到-1,这并不好。如果您想像尝试那样做,那么您需要有一种方法可以简单地移回先前填充的单元格,而不管您所在的行或列如何。试试这个:for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++){&nbsp; &nbsp; array[x % array.GetLength(0), x / array.GetLength(0)] = r.Next(10, 100);&nbsp; &nbsp; for (int y = 0; y < x; y++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (array[x % array.GetLength(0), x / array.GetLength(0)] == array[y % array.GetLength(0), y / array.GetLength(0)])&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }}但是,这不是很有效。试试这个:var values = Enumerable.Range(10, 90).OrderBy(_ => r.Next()).ToArray();for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++){&nbsp; &nbsp; array[x % array.GetLength(0), x / array.GetLength(0)] = values[x];}

慕森卡

所以,首先,这似乎效率低下。不知道你为什么要这样做,但话又说回来,不知道原因。看起来像一个编程任务。我猜,你需要某种双重休息。当您中断查找匹配项时,您不会中断到“k”for 循环,因此即使您找到了一个匹配项,您仍会继续查找匹配项。尝试设置一个布尔值来表示已找到,然后在 k 的 for 循环的条件中使用它。这将打破它,让你重新开始 i 和 j 的外部循环。即使那样,它也不会起作用,因为您不加选择地减去了 i 和 j。因此,如果您位于位置 1,2,您将跳回到 0,1 而不是 1,2。所以你需要减去j,如果它降到0以下,然后从i中减去并将“array.GetLength(1)”添加到j。

慕无忌1623718

此解决方案取决于HashSet包含唯一元素的属性。它有一个Add方法,false当我们尝试添加现有元素时返回。Random r = new Random();int[,] array = new int[10, 8];var usedValues = new HashSet<int>();for (int i = 0; i < array.GetLength(0); i++){&nbsp; &nbsp; for (int j = 0; j < array.GetLength(1); j++)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; int uniqueValue;&nbsp; &nbsp; &nbsp; &nbsp; while (true)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uniqueValue = r.Next(10, 100);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (usedValues.Add(uniqueValue)) break; // It is unique indeed&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // It is not unique, try again.&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; array[i, j] = uniqueValue;&nbsp; &nbsp; }}当可接受的唯一值范围较大时,上述解决方案更适用。在这种特定情况下,范围非常小(10-99),@Enigmativity 提供的解决方案更可取。
打开App,查看更多内容
随时随地看视频慕课网APP