【问题标题】:filling multidimensional array with unique numbers in C#在 C# 中用唯一数字填充多维数组
【发布时间】:2013-07-12 11:55:21
【问题描述】:

我正在尝试编写一个用唯一数字填充数组的代码。

我可以分别为 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 维数组执行类似操作?

【问题讨论】:

  • 您的代码仅检查该数字在数组的同一切片中是否唯一。这是意图,还是该数字在整个数组中应该是唯一的?
  • UPS。我从来没有注意到这一点。你说的对。它在整个数组中应该是唯一的。

标签: c# arrays random unique multidimensional-array


【解决方案1】:

在前两个 for 循环中,您正在正确分析数组(ij 从相应维度的开头到结尾)。问题出现在您引入“更正”的最内部部分,这实际上引发了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--;

【讨论】:

    【解决方案2】:

    我的方法是从一维唯一数字数组开始,您可以将其随机排列,然后插入真实数组中的适当位置。

    这里是主要功能:

    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);
    

    我的策略将序列号分配给原始一维数组以确保唯一性,但您可以根据需要采用不同的策略。

    【讨论】:

      【解决方案3】:

      您可以使用Rank 属性来获取数组中的总维数

      插入使用SetValue方法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-07
        • 2017-06-29
        • 2011-01-11
        • 1970-01-01
        相关资源
        最近更新 更多