用C#中的唯一数字填充多维数组
本文关键字:填充 数组 数字 唯一 | 更新日期: 2023-09-27 18:22:26
我正在尝试编写一个代码,用唯一的数字填充数组。
我可以分别为1、2和3维数组编写代码,但for
循环的数量增长到"无穷大"。
这是二维阵列的代码:
static void fillArray(int[,] array)
{
Random rand = new Random();
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = rand.Next(1, 100);
for (int k = 0; k < j; k++)
if (array[i, k] == array[i, j])
j--;
}
}
print_info(array);
}
有可能对n维数组执行这样的操作吗?
我的方法是从一个由唯一数字组成的一维数组开始,您可以对其进行洗牌,然后将其放入真实数组中的适当位置。
以下是主要功能:
private static void Initialize(Array array)
{
var rank = array.Rank;
var dimensionLengths = new List<int>();
var totalSize = 1;
int[] arrayIndices = new int[rank];
for (var dimension = 0; dimension < rank; dimension++)
{
var upperBound = array.GetLength(dimension);
dimensionLengths.Add(upperBound);
totalSize *= upperBound;
}
var singleArray = new int[totalSize];
for (int i = 0; i < totalSize; i++) singleArray[i] = i;
singleArray = Shuffle(singleArray);
for (var i = 0; i < singleArray.Length; i++)
{
var remainingIndex = i;
for (var dimension = array.Rank - 1; dimension >= 0; dimension--)
{
arrayIndices[dimension] = remainingIndex%dimensionLengths[dimension];
remainingIndex /= dimensionLengths[dimension];
}
// Now, set the appropriate cell in your real array:
array.SetValue(singleArray[i], arrayIndices);
}
}
本例中的关键是array.SetValue(value, params int[] indices)
函数。通过建立正确的索引列表,可以使用此函数在数组中设置任意单元格。
这里是Shuffle
函数:
private static int[] Shuffle(int[] singleArray)
{
var random = new Random();
for (int i = singleArray.Length; i > 1; i--)
{
// Pick random element to swap.
int j = random.Next(i); // 0 <= j <= i-1
// Swap.
int tmp = singleArray[j];
singleArray[j] = singleArray[i - 1];
singleArray[i - 1] = tmp;
}
return singleArray;
}
最后是它在使用中的演示:
var array1 = new int[2,3,5];
Initialize(array1);
var array2 = new int[2,2,3,4];
Initialize(array2);
我的策略为原始的一维数组分配序列号以确保唯一性,但您可以根据需要采用不同的策略。
您可以使用Rank属性来获取数组中的维度总数
要插入,请使用SetValue方法
在前两个for循环中,您正在正确分析数组(i
和j
从相应维度的开始到结束)。问题出现在最内部的部分,您引入了一个"更正",它实际上会引发j
的无休止循环。
First iteration:
- First loop: i = 0;
- Second loop: j = 0;
- Third loop: j = -1
Second iteration
- First loop: i = 0;
- Second loop: j = 0;
- Third loop: j = -1
. etc., etc.
(我的分析是在第一次使用内部循环的那一刻开始的。还要记住,就涉及随机数而言,无法预测确切的行为。但我们的想法是,通过遵循任意规则,使j
计数器一次又一次地返回)。
你到底想完成什么?最后一次修正(引发无休止循环的修正)是为了做什么?
如果你唯一想做的就是检查之前存储的值,那么你必须依赖一个不同的变量(例如j2),它不会影响上面的任何循环:
int j2 = j;
for (int k = 0; k < j2; k++)
if (array[i, k] == array[i, j2])
j2--;