版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/46437485
用已知字符串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);
}
}
}
下面是程序的运行结果:
总体来说,这个算法的思路还是比较简单的。