为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
长风秋雁 2022-12-24 12:46:46
刚开始学习编程,我需要没有重复的二维数组。这段代码(为 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;                        }                    }                }            }        }
查看完整描述

3 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

使用嵌套j循环,您将为每个填充整个第二个维度i,但在k和l循环中,您只检查当前单元格左上角的网格。您可以放置一个数字两次,因为您没有检查每个以前填充的位置。


如果我们把代码改成这样:


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

        {

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

            {

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

                {

                    i--;

                    j--;

                    break;

                }

            }

        }

然后你消除了那个问题,但你很快发现你得到了一个IndexOutOfRangeException,因为你同时递减了两个i& j。这并没有将您移动到以前的值 - 它跳回一整行并留下一个单元格 - 最终发送i或发送j到-1,这并不好。


如果您想像尝试那样做,那么您需要有一种方法可以简单地移回先前填充的单元格,而不管您所在的行或列如何。


试试这个:


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

{

    array[x % array.GetLength(0), x / array.GetLength(0)] = r.Next(10, 100);

    for (int y = 0; y < x; y++)

    {

        if (array[x % array.GetLength(0), x / array.GetLength(0)] == array[y % array.GetLength(0), y / array.GetLength(0)])

        {

            x--;

            break;

        };

    }

}

但是,这不是很有效。试试这个:


var values = Enumerable.Range(10, 90).OrderBy(_ => r.Next()).ToArray();


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

{

    array[x % array.GetLength(0), x / array.GetLength(0)] = values[x];

}


查看完整回答
反对 回复 2022-12-24
?
慕森卡

TA贡献1806条经验 获得超8个赞

所以,首先,这似乎效率低下。不知道你为什么要这样做,但话又说回来,不知道原因。看起来像一个编程任务。

我猜,你需要某种双重休息。当您中断查找匹配项时,您不会中断到“k”for 循环,因此即使您找到了一个匹配项,您仍会继续查找匹配项。尝试设置一个布尔值来表示已找到,然后在 k 的 for 循环的条件中使用它。这将打破它,让你重新开始 i 和 j 的外部循环。

即使那样,它也不会起作用,因为您不加选择地减去了 i 和 j。因此,如果您位于位置 1,2,您将跳回到 0,1 而不是 1,2。所以你需要减去j,如果它降到0以下,然后从i中减去并将“array.GetLength(1)”添加到j。


查看完整回答
反对 回复 2022-12-24
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

此解决方案取决于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++)

{

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

    {

        int uniqueValue;

        while (true)

        {

            uniqueValue = r.Next(10, 100);

            if (usedValues.Add(uniqueValue)) break; // It is unique indeed

            // It is not unique, try again.

        }

        array[i, j] = uniqueValue;

    }

}

当可接受的唯一值范围较大时,上述解决方案更适用。在这种特定情况下,范围非常小(10-99),@Enigmativity 提供的解决方案更可取。



查看完整回答
反对 回复 2022-12-24
  • 3 回答
  • 0 关注
  • 203 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信