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];
}
TA贡献1806条经验 获得超8个赞
所以,首先,这似乎效率低下。不知道你为什么要这样做,但话又说回来,不知道原因。看起来像一个编程任务。
我猜,你需要某种双重休息。当您中断查找匹配项时,您不会中断到“k”for 循环,因此即使您找到了一个匹配项,您仍会继续查找匹配项。尝试设置一个布尔值来表示已找到,然后在 k 的 for 循环的条件中使用它。这将打破它,让你重新开始 i 和 j 的外部循环。
即使那样,它也不会起作用,因为您不加选择地减去了 i 和 j。因此,如果您位于位置 1,2,您将跳回到 0,1 而不是 1,2。所以你需要减去j,如果它降到0以下,然后从i中减去并将“array.GetLength(1)”添加到j。
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 提供的解决方案更可取。
- 3 回答
- 0 关注
- 246 浏览
添加回答
举报