用于在给定符号集上生成长度为k的所有字符串的C代码。任何字符串都不应重复符号。 例: 取英文字母{a,b,c,d,e,f}和k = 3中的6个小写符号;打印输出的前25个字符串,按字典顺序排序。
有人可以帮帮我吗?
修改
# include <stdio.h>
# include <conio.h>
void swap (char *x, char *y)
{
char temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(char *a, int i, int n)
{
int j;
if (i == n)
printf("%s\n", a);
else
{
for (j = i; j <= n; j++)
{
swap((a+i), (a+j));
permute(a, i+1, n);
swap((a+i), (a+j));
}
}
}
int main()
{
char a[] = "ABC";
permute(a, 0, 2);
getchar();
return 0;
}
然而,这将给出所有字母表的排列。用空格替换要进行参数化的字母表似乎没有办法!
即使用可置换的空格重复调用置换也没有效率。
答案 0 :(得分:3)
假设您的字符池已排序且没有重复(可能需要一些预处理),则按字典顺序生成所需的字符串是自动的(在我想到的方法中)。
查看可以使用限制从“ABC”生成的所有非空字符串的简短示例:
A
AB
ABC
AC
ACB
B
BA
BAC
BC
BCA
C
CA
CAB
CB
CBA
您需要跟踪
int
和char[]
int
和bool[]
(或char[]
,int[]
)您还需要输出多少个字符串,因为它会在递归调用中被修改:int*
void permute(char * pool,int pool_length,int num_picked,char * stringy, bool * picked,int max_length,int * strings_left){
int i;
for(i = 0; *string_left > 0 && i < pool_length; ++i) {
if (pool[i] may be picked) {
// 1. pick that as the num_picked + 1st character
// 2. output and decrement *strings_left
// 3. recur
// 4. unpick pool[i]
}
}
}
我希望有所帮助,而且我没有给予太多帮助。
答案 1 :(得分:2)
代码看起来像将打印字母表排列的代码,但代码中的k代表在哪里?在没有长度k之后,你没有任何机制可以使你的代码停止递归。
另外,我认为在permute函数中调用printf()时可能会遇到问题。如果permute函数返回一个字符串更有意义,那么你可以printf它返回的内容。
编辑:
递归的基本概念是通过求解其自身的较小版本来解决问题。
所以让我们说你的字母是{'A','B','C'},你想要归还的是:
“A”然后“A”连同所有有效的返回值{'B','C'}
“B”然后“B”连同所有有效的返回值{'A','C'}
“C”然后“C”连同所有有效的返回值{'A','B'}