我希望创建一个函数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
进行循环,并且不确定如何处理。我考虑过递归,但没有成功。任何帮助将不胜感激。
答案 0 :(得分:3)
实际上,您可以 遍历尺寸。请看看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
答案 1 :(得分:0)
我知道这是一篇旧文章,但是我为这个问题创建了解决方案。
让我用示例脚本解决这个问题。
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 }
的上限。
我希望我已经解释清楚了。谢谢