递归与分治算法之字符全排列
一、问题描述
设R={r1,r2,r3,…rn}是要进行全排列的n个元素,设Ri =R-{ri}.集合X中元素的全排列记为Perm(X)。(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列。R的全排列可归纳定义如下:
当n=1时,Perm(R)=(r),其中r是集合R中唯一的元素
当n>1时,Perm(R)由(r1)Perm(R1),r2Perm(R2),…..(rn)Perm(Rn)构成.
三、C语言算法实现
/*
编程实现n个元素的全排列的递归算法(P13),并在此基础上修改程序,
使其能解决有重复元素的排列问题(P41算法实现题2-5)。
*/
#include<stdio.h>
int count=0;
//检查是否与之前元素有重复
bool Check(char list[], int k,int i)
{
for(int j = k;j < i;j++)
{
if(list[j] == list[i])
return false;
}
return true;
}
//交换
void Swap(char &a,char &b)
{
char temp = a ; a = b ; b = temp;
}
//产生list[k:m]的所有排列
void Perm(char list[],int k,int m)
{
if(k == m) //已经递归到最后一个元素
{
//打印当前排列
for(int i = 0;i <= m;i++)
{
printf("%c",list[i]);
}
printf("\n");
count++;
}
else //还有多个元素等待排列,递归产生排列
{
for(int i = k;i <= m;i++)
{
if( Check(list,k,i))
{
Swap(list[k],list[i]);
Perm(list,k+1,m);
Swap(list[k],list[i]);
}
}
}
}
void main()
{
char list[10];
int l;
printf("请输您要输入的序列的长度!\n");
scanf("%d",&l);
printf("请输入一个序列!\n");
scanf("%s",list);
printf("该序列的全排列如下:\n");
Perm(list,0,l-1);
printf("该序列共有%d种排列顺序!\n",count);
}