如果我想枚举多个有界值的所有组合,那就很容易了:
for(int i = 0; i <= iMax; i++)
{
for(int j = 0; j <= jMax; j++)
{
for(int k = 0; k <= kMax; k++)
{
DoSomething(i,j);
}
}
}
同样,如果我想枚举单个无界值,检查某些条件,那也很容易:
BigInteger i = 0;
while(true)
{
if(Condition(i)) { break; }
i++;
}
但是如何枚举多个无界值的所有组合呢?对于两个人,我意识到的一种方式是&#34; zig-zag&#34;,就像这样:
BigInteger i = 0;
BigInteger j = 0;
bool direction = true;
while(true)
{
if(Condition(i,j)) { break; }
if(direction)
{
if(j==0)
{
direction = false;
i++;
}
else
{
i++;
j--;
}
}
else
{
if(i==0)
{
direction = true;
j++;
}
else
{
j++;
i--;
}
}
}
这将产生的前几个(i
,j
)对是:(0,0),(1,0),(0,1),(0,2),( 1,1),(2,0),(3,0),(2,1),(1,2)......
所以我的问题是:这个或其他方法如何适应两个以上的维度?例如如果我想循环遍历i
,j
和k
?
注意:我知道有更好的方法来编写这些示例,为了简单起见,我只是尽可能简单地编写它们。
答案 0 :(得分:2)
for(limit=0;;++limit) {
for(i0=0; i0<=limit; ++i0) {
for(i1=0; i1<=limit-i0; ++i1) {
for(i2=0; i2<=limit-i0-i1, ++i2) {
for(i3=0; i3<=limit-i0-i1-i2, ++i3) {
int i4 = limit-i0-i1-i2-i3;
//do stuff with i0, i1, i2, i3, i4; break when had enough
}}}}}}
答案 1 :(得分:1)
在2D中:生成所有对(j,k),使得j + k == i,用于增加i。
for (i= 0; true; i++)
for (j= 0, k= i; 0 <= k; j++, k--)
i=0 -> (0, 0)
i=1 -> (0, 1), (1, 0)
i=2 -> (0, 2), (1, 1), (2, 0)
...
在3D中:生成所有三元组(j,l,m),使得l + m == j用于增加j,j + k = i,用于增加i。
for (i= 0; true; i++)
for (j= 0, k= i; 0 <= k; j++, k--)
for (l= 0, m= j; 0 <= m; l++, m--)
i=0, j=0 -> (0, 0, 0)
i=1, j=0 -> (0, 0, 1), (0, 1, 0)
i=1, j=1 -> (1, 0, 1), (1, 1, 0)
i=2, j=0 -> (0, 0, 2), (0, 1, 1), (0, 2, 0)
i=2, j=1 -> (1, 0, 2), (1, 1, 1), (1, 2, 0)
i=2, j=2 -> (2, 0, 2), (2, 1, 1), (2, 2, 0)
...
答案 2 :(得分:0)
因此,正如您所提到的,一个维度很容易。从零开始计算。
两个也不是那么难,只是沿着对角线计算:
11 7 12 4 8 13 2 5 9 14 1 3 6 10 15
对于三个维度,我们可以想象一个金字塔,每次我们都会添加一个新的shell:
在这里,数字将代表该位置的高度,而不是每个项目的添加顺序。
1
1 2 1
1 2 1 3 2 1
您可以将此三维图设想为在球体周围添加贝壳(但移动到离散的,不连续的比例),将二维版本添加为同心圆,将一维版本设置为这些同心圆的半径。当然,在所有情况下,我们只有1/4的图片,因为您将所有内容限制为正值。
那么,我们如何在第n种情况下这样做。
好吧,每个shell由每个维度的每个值组合表示,使得它们的总和是一些常量。首先,您找到每个维度的自然数值的每个组合,使得它们的总和为1
,然后您找到总计为2
的所有组合,然后您找到所有总和的组合最多3,你继续无限。
答案 3 :(得分:-1)
这确实是一个组合问题,而不是计算机编程问题。
无论如何,你可以这样处理这个无限多变量问题:
At level 0, you have 1 problem to check [0,0,0]
At level 1, you have 3 problems to check ([0,0,1],[0,1,0],[1,0,0])
At level 2, you have 6 problems ([0,0,2],[0,2,0],[2,0,0],[0,1,1],[1,0,1],[1,1,0])
所以你必须为每个级别生成所有可能性(递归可以帮助)