在C中生成所有可能的数组值组合

时间:2016-12-01 21:08:37

标签: c combinations

我有一个从0到k的N个值的数组(0 <= k <= N),我需要生成所有可能的N值组合

int DD = (str[1] - '0') * 10 + str[2] - '0';

对于这个测试(N = 2 K = 2)我有那些组合

void generate(int n, int k) {
   int q = -1;
   char res = '|';
   int r; 
   int j;
   for (j = 1; j <= n; j++) {
       q = j / (k + 1);
       r = j % (k + 1);
       printf("%d %c", r, res);
    }
}
int main() {
   int n = 2;
   int k = 2;
   int i, nbr_comb; 
   nbr_comb = pow((k + 1), n); number of combinations

   for (i = 0; i < nbr_comb; i++) {
       generate(n, i);
       printf("\n");
   }
   return (EXIT_SUCCESS);
}

你看到它开始生成但它固定在一个点上,我找不到原因! ?

预期示例: 对于n = 2k = 2n = 3k = 2

0 |0 |
1 |0 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |

1 个答案:

答案 0 :(得分:1)

这是你的循环在n = 2,k = 2时展开的方式:

for (i=0; i<nbr_comb; i++)
  i=0:  generate(2,0) -->   j=1:  1 mod 1 = 0
                            j=2:  2 mod 1 = 0
  i=1:  generate(2,1) -->   j=1:  1 mod 2 = 1
                            j=2:  2 mod 2 = 0
  i=2:  generate(2,2) -->   j=1:  1 mod 3 = 1
                            j=2:  2 mod 3 = 2
  i=3:  generate(2,3) -->   j=1:  1 mod 4 = 1
                            j=2:  2 mod 4 = 2
  i=4:  generate(2,4) -->   j=1:  1 mod 5 = 1
                            j=2:  2 mod 5 = 2
  i=5:  generate(2,5) -->   j=1:  1 mod 6 = 1
                            j=2:  2 mod 6 = 2
  i=6:  generate(2,6) -->   j=1:  1 mod 7 = 1
                            j=2:  2 mod 7 = 2
  i=7:  generate(2,7) -->   j=1:  1 mod 8 = 1
                            j=2:  2 mod 8 = 2
  i=8:  generate(2,8) -->   j=1:  1 mod 9 = 1
                            j=2:  2 mod 9 = 2

正如您所看到的,j for-loop中的generate()只是在j上继续调用模数,其结果将始终为j一次参数k大于j

你需要的是一个嵌套的for循环,它将当前组合(范围[0..(k+1)^n])和当前数组索引(范围[0..n-1])在决定从哪个值打印时考虑[0..k]的集合。

如果您将输出视为行和列,那么在最右侧的列中,值应在每行上更改,从0..k开始迭代。在下一列中,值应更改每(k+1)th行。在下一列中,值应更改每(k+1)^2行。

例如,当n = 3且k = 2时,对于前9行,最右边的列应该看起来像0,1,2,0,1,2,0,1,2。中间列应该看起来像0,0,0,1,1,1,2,2,2。最左侧的列应该看起来像0,0,0,0,0,0,0,0,0

因此,你最终得到这样的东西:

   int n = 2;
   int k = 2;
   int row, col; 
   int cell;
   int rdiv;
   int nbr_comb = pow(k+1, n);

   for (row=0; row < nbr_comb; row++) 
   {
       for (col=n-1; col>=0; col--)
       {
           rdiv = pow(k+1, col);
           cell = (row/rdiv) % (k+1);
           printf("%d |", cell);
       }
       printf("\n");
   }