如何创建所有数字组合的n维数组?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何创建所有数字组合的n维数组?相关的知识,希望对你有一定的参考价值。
我想创建一个函数AllCombnations(d, maxValue)
,它将创建一个从0到maxValue
的所有数字组合的d维数组。
例如,在0到maxValue
中创建3D空间中所有数字组合的硬编码版本可能类似于:
for (int i = 0; i < maxValue; i++)
for (int j = 0; j < maxValue; j++)
for (int k = 0; k < maxValue; k++)
{
// code here
}
我面临的问题是我无法将n
用于循环,并且我不确定如何解决这个问题。我考虑过递归,但没有成功。任何帮助将不胜感激。
实际上,您可以循环维度。请看看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 }
的上限。
我希望我已经很好地解释了这一点。谢谢
以上是关于如何创建所有数字组合的n维数组?的主要内容,如果未能解决你的问题,请参考以下文章
很难创建一个按升序显示 n 个数字 (0<n<10) 的所有不同组合的函数
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段