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

Posted

技术标签:

【中文标题】在 C 中生成所有可能的数组值组合【英文标题】:generate all possible combinations of array values in C 【发布时间】:2017-04-16 16:00:58 【问题描述】:

我有一个从 0 到 k (0

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=2 K=2) 我有这些组合

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

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

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

0 0            0 0 0
0 1            0 0 1  
0 2            0 0 2
1 0            1 0 0
1 1            1 0 1 
1 2            1 0 2
2 0            1 1 0 
2 1            1 1 1
2 2            1 1 2
               1 2 0
               1 2 1 
               1 2 2
               2 0 0
               .....

【问题讨论】:

Algorithm to return all combinations of k elements from n的可能重复 我确实读过这个,它不是组合而是排列,它不接受 N 中重复的 k 值,在我的情况下,我需要所有可能的组合,即使是具有重复值的组合,例如 (0|0|1 - 2|1|2 ...) rosettacode.org/wiki/Combinations_with_repetitions#C 有什么问题? 这段代码只是选择不会产生所有可能性的选择 我不认为我完全理解 N 和 K 代表什么,但预期的结果应该是 000, 001, 002, 010,... 222。对吧? 【参考方案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

如您所见,generate() 中的j for-loop 只是不断对j 进行取模,一旦参数k 大于j,其结果将始终为j

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

如果您将输出视为行和列,那么在最右边的列中,每一行的值都应该改变,从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");
   

【讨论】:

以上是关于在 C 中生成所有可能的数组值组合的主要内容,如果未能解决你的问题,请参考以下文章

Javascript - 在单个数组中生成所有元素组合(成对)

按位移位以在 C 中生成所有可能的排列 [重复]

在sql中生成数据组合

在python中生成组合

ruby - 如何从字符串数组中生成可能的字母顺序组合?

PHP算法从单个集合中生成特定大小的所有组合