我正在尝试在C中找到一个有效的算法,它为我提供了给定字符集的所有组合。
算法不应该递归。最后,位数应该是灵活的。例如:
char set[] = "a1";
->
a1
aa
1a
11
我只找到了Perl解决方案,但它使用了substr()
。我认为这不是那么快的表现。
对于C语言中的大多数算法,我发现只有排列...
德国C ++论坛上的一篇文章称,C ++ - STL解决方案比“原始”递归算法更快。
答案 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到(数字计数乘以基数)并每次调用你的函数。