繁体   English   中英

如何创建所有数字组合的n维数组?

[英]How to create a n-dimensional array of all combination of number?

我希望创建一个函数AllCombnations(d, maxValue) ,它将创建一个从0到maxValue的所有数字组合的d维数组。

例如,在3D空间中创建所有数字组合的硬编码版本,从0到maxValue可能类似于:

for (int i = 0; i < maxValue; i++)
    for (int j = 0; j < maxValue; j++)
        for (int k = 0; k < maxValue; k++)
        {
            // code here
        }

我面临的问题是我无法嵌套 n for循环,我不确定如何去做。 我考虑过递归,但没有成功。 任何帮助将不胜感激。

实际上,您可以循环维度。 请看看Array

演示:

                    // [6, 6, 6] array
int rank = 3;       // 3D array - 3 dimensions
int maxValue = 6;   // Each dimension is of size 6

int[] lengths = Enumerable // {6, 6, 6} - lengths of the dimensions:
  .Repeat(maxValue, rank)  // rank times maxValue 
  .ToArray();              // materialized as array

//TODO: put the right type of arrays' items 
// In demo, let array be of type string: "string[6, 6, 6] array"
var array = Array.CreateInstance(typeof(string), lengths);

// we can't use hardcoded set (i, j, k) of variables 
// we have to address array's item via array of rank length
int[] address = new int[array.Rank];

// Single loop over all array's items (and dimensions)
do {
  //TODO: put the right value here by given address:
  //      (i == address[0], j == address[1], k == address[2] etc.)
  array.SetValue(
    string.Concat(address.Select(i => (char) (i + 'A'))), // value: "AAA", "AAB" etc. 
    address);                                             // address: [0,0,0], [0,0,1], 

  // here we compute next address
  for (int i = 0; i < address.Length; ++i)
    if (address[i] >= array.GetLength(i) - 1)
      address[i] = 0;
    else {
      address[i] += 1;
      break;
    }

  // if we get {0, 0, ..., 0} address, we've exhausted all the items
}
while (!address.All(index => index == 0));

我们来看看这个数组( 20顶级项目):

  Console.WriteLine(string.Join(Environment.NewLine, array.OfType<string>().Take(20)));

结果:

AAA
AAB
AAC
AAD
AAE
AAF
ABA
ABB
ABC
ABD
ABE
ABF
ACA
ACB
ACC
ACD
ACE
ACF
ADA
ADB

我知道现在这是一个旧帖子,但是我为这个问题创建了一个解决方案。

让我通过一个示例脚本来解决这个问题。

class Program
{
    static void Main()
    {
        // Print all combinations from a to b, for n dimensions
        // e.g. 0000 to 2222 <- each dimension goes from 0 to 2, with 4 dimensions
        // Note that each dimension can have a unique start/end point
        // e.g. 1234 to 5678, so the 2nd dimensions is bound 2 <= x <= 6

        int dimensions = 4;
        int[] startValues = { 0, 0, 0, 0 };
        int[] endValues = { 2, 2, 2, 2 };

        PrintCombinations(startValues, endValues, dimensions);

        Console.ReadKey();
    }

    /// <summary>
    /// Prints all combinations of numbers given inputs
    /// </summary>
    /// <param name="start">Inclusive stating integers</param>
    /// <param name="end">Inclusive ending integers</param>
    /// <param name="dimensions">The number of dimensions to iterate</param>
    private static void PrintCombinations(int[] startValues, int[] endValues, int dimensions)
    {
        // Create new array to loop through without disturbing the original array
        int[] loopArray = (int[])startValues.Clone();

        // Loop through each value
        while (!Enumerable.SequenceEqual(loopArray, endValues))
        {
            // Write array to console
            Console.WriteLine($"{string.Join(", ", loopArray)}");

            // Increment array
            loopArray[0]++;

            // Check if a dimension is larger than it's maximum, then set to min, and add +1 to next dimension
            // Do not do this for last dimension, as loop will break once the final combination is met
            for (int i = 0; i < dimensions - 1; i++)
                if (loopArray[i] > endValues[i])
                {
                    loopArray[i] = startValues[i];
                    loopArray[i + 1]++;
                }
        }

        // Write final array combination  to console
        Console.WriteLine($"{string.Join(", ", loopArray)}");
    }
}

这是一个足够简单的例子来说明我是如何想要扩展“多维度”这个数组的概念。

如果查看PrintCombinations的底部,您将看到以下代码:

for (int i = 0; i < dimensions - 1; i++)
    if (loopArray[i] > endValues[i])
    {
        loopArray[i] = startValues[i];
        loopArray[i + 1]++;
    }

这是我通过多个维度提出循环的代码,当您有用户提交的维度和其他信息时,无需硬编码循环(如上面的示例所示)。

基本上,此代码将每个维度的VALUE存储在数组中。 让我们做一个3维度的例子,(x,y,z)。 我们可以说点(x,y,z)= int [] {x,y,z}如果我们说x,y和z是数组的上界,我们可以通过减去数组来循环遍历这个数组第一个维度,直到它达到零,然后从下一个维度中删除一个,直到它达到零等,同时将维度重置为上限,或者在此示例中,从零添加到上限,然后重置为零,并增加以下维度。

通过使用其他数组的上限和下限,您基本上可以在两个特定范围之间进行嵌套循环。 在上面的例子中,我使用了{ 2, 2, 2, 2 } 2,2,2,2 { 2, 2, 2, 2 }的上限。

我希望我已经很好地解释了这一点。 谢谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM