🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
用已知字符串s中的字符,生成由其中n个字符组成的所有字符的排列。设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次。 例如,对于s[]=”abc”,n=2,则所有字符的排列有:ba,ca,ab,cb,ac,bc。 算法思想: 使用递归完成该实例。 - 举个例子: - s = “abc”,n=2 - 则第一个perm(n,s),即perm(2,”abc”); - 首先需要判断w中的字符个数是否满足,n=2>1,表示还没有满足 - 首先,从s的第一个元素开始,s[1] = ‘a’; - 填充到w中,w[n-1]即,w[1] = ‘a’; - 紧接着,进行一些调整,使得s1 = bc,n=1 - 进行同样的perm,即perm(1,”bc”);同样先进行判断 - 选择b填充到w中,在进入perm(0,”c”),判断输出 - 接着,回到上一层,perm(1,”bc”),再选择字符”c”进入w - 选择c进入w之后,进行一些调整,将s1调整成这样一个字符串s1=”cb”, - 这样进入perm(0,”b”),判断输出. * - 接着,进入第一层,由于ba,ca都已经输出完毕,第一个元素从b开始进行选择 - 首先将b放入w中,即w[1] = ‘b’;接着进行一些调整,将s1调整为s1 = “bac”; - 进入perm(1,”ac”); - 以此方式进行递归,完成。 下面是代码实现部分: ~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 20 char w[N]; void perm(int n,char *s); /** * 用已知字符串s中的字符,生成由其中n个字符组成的所有字符的排列。 * 设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次。 * 例如,对于s[]="abc",n=2,则所有字符的排列有:ba,ca,ab,cb,ac,bc。 */ int main() { char s[N]; int n; printf("Please enter the char array:\n"); scanf("%s",&s); printf("Please number:\n"); scanf("%d",&n); perm(n,s); //调用排列函数 return 0; } /** * 举个例子: * s = "abc",n=2 * 则第一个perm(n,s),即perm(2,"abc"); * 首先需要判断w中的字符个数是否满足,n=2>1,表示还没有满足 * 首先,从s的第一个元素开始,s[1] = 'a'; * 填充到w中,w[n-1]即,w[1] = 'a'; * 紧接着,进行一些调整,使得s1 = bc,n=1 * 进行同样的perm,即perm(1,"bc");同样先进行判断 * 选择b填充到w中,在进入perm(0,"c"),判断输出 * 接着,回到上一层,perm(1,"bc"),再选择字符"c"进入w * 选择c进入w之后,进行一些调整,将s1调整成这样一个字符串s1="cb", * 这样进入perm(0,"b"),判断输出. * * 接着,进入第一层,由于ba,ca都已经输出完毕,第一个元素从b开始进行选择 * 首先将b放入w中,即w[1] = 'b';接着进行一些调整,将s1调整为s1 = "bac"; * 进入perm(1,"ac"); * 以此方式进行递归,完成。 */ void perm(int n,char *s){ if(n < 1){ //如果n小于1,表示w中的长度已经达到需要的长度 printf("%s\n",w); return; }else{ char s1[N]; //临时变量存储 strcpy(s1,s); int i; for(i = 0;*(s1+i);i++){ //从s1中选择一个字符放入w对应的位置中 *(w+n-1) = *(s1+i); //将从s1中被选择的字符替换成第一个字符 *(s1+i) = *s1; //将第一个字符换成被选择的字符 *s1 = *(w+n-1); perm(n-1,s1+1); } } } ~~~ 下面是程序的运行结果: ![这里写图片描述](https://box.kancloud.cn/2016-05-24_5743c075edd44.jpg "") 总体来说,这个算法的思路还是比较简单的。