C语言例程:字符排列

从键盘读入实数

实例说明

用已知字符串 s 中的字符,生成由其中 n 个字符组成的所有字符排列。设 n 小于字符串 s 的字符个数,其中 s 中的字符在每个排列中最多出现一次。例如,对于 s[ ]=“abc”,n=2,则所有字符排列有:ba,ca,ab,cb,ac,bc。

实例解析

可采用递归方法来生成用字符串 s 中的字符生成由 n 个字符组成的字符排列。设程序用字符数组 w[ ]存储生成的字符排列。令递归函数为 perm(int n,char *s),其功能是用字符串 s 中的字符生成由 n 个字符组成的所有排列。其方法是从字符串 s 依次选用其中的每个字符填写到字符排列的第 n 个位置(w[n-1])中,然后通过递归调用生成由 n-1 个字符组成的排列。当一个字符被选用后,进一步递归调用时可选用的字符中应不再包含该字符。另外,当发现一个字符排列生成后,就不再递归调用,而是输出生成的字符列。综合以上的思路,函数 perm(int n, char *s)的算法如下。

[算法]函数 perm(int n, char *s)的算法

{ 
 if(一个排列已经生成)printf("%s\n",w); 
 else 
 { 
 保存本层可使用的字符串; 
 依次选本层可用字符循环完成以下工作; 
 { 
 将选用字符填入正在生成的字符排列中; 
 形成进一步递归可使用的字符串; 
 递归调用; 
 } 
 } 
 }

程序代码

#define N 20 
char w[N]; 
perm(int n, char *s) 
{ 
 char s1[N]; 
 int i; 
 if(n<1) 
 printf("%s\n",w); /* 一个排列生成输出 */ 
 else 
 { 
 strcpy(s1,s); /* 保存本层可使用的字符 */ 
 for(i=0;*(s1+i);i++) /* 依次选本层可用字符 */ 
 { 
 *(w+n-1)=*(s1+i);/* 将选用字符填入正在生成的字符排列中 */ 
 *(s1+i)=*s1; 
 *s1=*(w+n-1); 
 perm(n-1,s1+1); /* 递归 */ 
 } 
 } 
} 
main() 
{ 
 int n=2; 
 char s[N]; 
 w[n]='\0'; 
 clrscr(); 
 printf("This is a char permutation program!\nPlease input a string:\n"); 
 scanf("%s",s); 
 puts("\nPlease input the char number of permuted:\n"); 
 scanf("%d",&n); 
 puts("The permuted chars are:\n"); 
 perm(n,s); 
 puts("\nPress any key to quit..."); 
 getch(); 
}

程序运行结果

在这里插入图片描述

归纳注释

在本例子中,当递归调用生成 0 个字符的排列时,一个字符排列已经生成。为保存本层次可使用的字符串,可引入一个字符数组。为存储进一步递归可使用的字符串,可做如下处理,因进一步递归可使用的字符总比本层次可使用的字符少一个字符,可把本层次正在选用的字符与其字符串中的首字符交换,而进一步递归可使用的字符串就是从次字符开始的字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文斗士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值