C中的所有可能组合

时间:2011-04-11 20:32:30

标签: c algorithm combinatorics

我正在尝试在C中找到一个有效的算法,它为我提供了给定字符集的所有组合。

算法不应该递归。最后,位数应该是灵活的。例如:

char set[] = "a1";
->
a1
aa
1a
11

我只找到了Perl解决方案,但它使用了substr()。我认为这不是那么快的表现。

对于C语言中的大多数算法,我发现只有排列...

德国C ++论坛上的一篇文章称,C ++ - STL解决方案比“原始”递归算法更快。

5 个答案:

答案 0 :(得分:2)

如果设置的大小是固定的N,那么它很简单 - 你可以只有N for个循环,每个循环嵌套在前一个循环中。既然你不能这样做并且你不能使用递归,你必须计算所需的总迭代次数(好像它是N ^ M),使用一个循环然后用/和%来计算数组索引每个角色应该是。你也最好使用多头,因为N ^ M变得很快。

答案 1 :(得分:2)

Python非常接近伪代码。

您可以将Python源代码读取到itertools.permutations,然后在C中复制。

这是有效的演示:

#!/usr/bin/env python
import itertools

s='a1'

print set(itertools.permutations(s*len(s), len(s)))

输出:

set([('1', '1'), ('a', '1'), ('a', 'a'), ('1', 'a')])

这是一种更简单的方法:

>>> s='a1'
>>> ['{}{}'.format(x,y) for x in s for y in s]
['aa', 'a1', '1a', '11']


>>> s='abc'
>>> ['{}{}{}'.format(x,y,z) for x in s for y in s for z in s]
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 
 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 
 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 
 'cca', 'ccb', 'ccc']

要展开列表理解,请使用NESTED LOOPS,如下所示:

>>> for x in s:
...    for y in s:
...       for z in s:
...          print '{}{}{}'.format(x,y,z)

答案 2 :(得分:2)

维基百科拥有n-ary Gray code的C代码。它应该可以通过使用数字作为输入数组的偏移量转换为您的问题。您需要进行一些动态分配来处理输入的任意长度。一种相关的方法是进行嵌套循环,只要输入就有一个循环计数器数组,另外一个计数器用于当前递增的那些循环计数器。例如。打印所有六位数的六位数字,需要修改以进行动态分配,但显示原则:

int i;
int length = 5;
int max = 6;
int counters[length];
for (i=0; i<length; i++)
    counters[i] = 0;
for(;;) {
    for (i=length-1; i>=0; i--)
        printf("%d", counters[i]);
    printf("\n");
    for(i=0; i<length; i++) {
        counters[i]++;
        if (counters[i] < max)
            break;
        else
            counters[i] = 0;
    }
    if (i >= length)
        break;
}

答案 3 :(得分:0)

好吧,我会给可能的组合编号,遍历数字并转换。

例如:要生成10个符号{'0','1',...,'9'}的所有大小3组合,我将从0循环到999并输出“000”到“999”

以同样的方式(有点),生成5个符号{'a','b',...,'e'}的所有大小3组合,我将从0循环到5 * 5 * 5- 1并输出基数为5的循环数,但是提供了符号。

答案 4 :(得分:0)

编写一个将整数转换为字符串十六进制数的函数,然后将该算法转换为基数36(a-z加0-9)数。使用一个for循环计数从1到(数字计数乘以基数)并每次调用你的函数。

  • 1变为1
  • 10成为
  • 35变为z
  • 36变为10
  • 46变为1a