用已知字符串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 "")
总体来说,这个算法的思路还是比较简单的。
- 前言
- 实例一:HelloWorld
- scanf函数学习
- 实数比较
- sizeof()保留字获取类型的大小
- 自增/自减学习
- C学习if条件判断和for循环
- C实现的九九乘法表
- C实现一个比较简单的猜数游戏
- 使用C模拟ATM练习switch..case用法
- 记录一个班级的成绩练习一维数组
- C数组实现矩阵的转置
- C二维数组练习
- 利用数组求前n个质数
- C实现万年历
- C实现数组中元素的排序
- C实现任意进制数的转化
- C判断一个正整数n的d进制数是否是回文数
- C使用递归实现前N个元素的和
- 钢材切割问题
- 使用指针比较整型数据的大小
- 指向数组的指针
- 寻找指定元素
- 寻找相同元素的指针
- 整数转换成罗马数字
- 字符替换
- 从键盘读入实数
- C实现字符行排版
- C实现字符排列
- C实例--判断一个字符串是否是回文数
- 通讯录的输入输出
- 扑克牌的结构定义
- 使用“结构”统计学生成绩
- 报数游戏
- 模拟社会关系
- 统计文件中字符个数
- C实现两个文件的内容输出到同一个屏幕