复杂的C程序

时间:2012-01-25 21:12:30

标签: c string

用于在给定符号集上生成长度为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;
}
然而,这将给出所有字母表的排列。用空格替换要进行参数化的字母表似乎没有办法! 即使用可置换的空格重复调用置换也没有效率。

2 个答案:

答案 0 :(得分:3)

假设您的字符池已排序且没有重复(可能需要一些预处理),则按字典顺序生成所需的字符串是自动的(在我想到的方法中)。

查看可以使用限制从“ABC”生成的所有非空字符串的简短示例:

A
AB
ABC
AC
ACB
B
BA
BAC
BC
BCA
C
CA
CAB
CB
CBA

您需要跟踪

  1. 您选择了多少个字符,以及以哪种顺序:intchar[]
  2. 您仍可以选择多少个字符以及哪个字符:intbool[](或char[]int[]
  3. 您还需要输出多少个字符串,因为它会在递归调用中被修改: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]
        }
    }
    

    }

  4. 我希望有所帮助,而且我没有给予太多帮助。

答案 1 :(得分:2)

代码看起来像将打印字母表排列的代码,但代码中的k代表在哪里?在没有长度k之后,你没有任何机制可以使你的代码停止递归。

另外,我认为在permute函数中调用printf()时可能会遇到问题。如果permute函数返回一个字符串更有意义,那么你可以printf它返回的内容。

编辑:

递归的基本概念是通过求解其自身的较小版本来解决问题。

所以让我们说你的字母是{'A','B','C'},你想要归还的是:

“A”然后“A”连同所有有效的返回值{'B','C'}
“B”然后“B”连同所有有效的返回值{'A','C'} “C”然后“C”连同所有有效的返回值{'A','B'}