您的位置:首页 > 其它

输入一个字符串输出它的全排列

2011-10-23 16:13 169 查看
#include <stdio.h>

#include <string.h>

#include <memory.h>

int m;//记录字符串长度

int n;//记录字符串中的字符种类数

char map[256];//记录是哪几种字符

int count[256];//记录每种字符有多少个

void Make_Map(char *str)//统计字符串的相关信息

{

int s[256];

int i;

memset(s,0,sizeof(s));

memset(count,0,sizeof(count));

m=strlen(str);

while(*str)

{

s[*str]++; //*str为字符,s[字符],字符转换成ASCII码,s[字符]++,同一种类字符计数,原来为0,

str++; //(接上)这是一种常见的映射.

}

n=0;

for (i=0;i<256;i++)

if (s[i])

{

map
=i; //n记录了字符种类数,map
记录了原来*str的值.

count
=s[i]; //count
记录每种字符的个数

n++;

}

}

int stack[1000];//递归用的栈,并记录当前生成的排列

void Find(int depth)//递归式回溯法生成全排列

{

int k=0;

if (depth==m)

{

int i;

for (i=0;i<depth;i++) {putchar(map[stack[i]]);

//printf("%d\n",k);

}

putchar('\n');

}

else

{

int i;

for (i=0;i<n;i++) //这里开始只用到map,count数组,他们分别记录了字符ascii,相同字符出现个数.

if (count[i])

{

stack[depth]=i; //先把这个值存到堆栈,

count[i]--; //后面递归不用这个值了,减掉一个

Find(depth+1); //假设这个能得到子序列的全排列

count[i]++; //处于当前循环中,恢复这个值,这是因为全排列的算法要求,

//考虑第一层,即取ri,对但是要对剩余的n-1个数取全排列



}

}

}

void main()

{

char str[1000];

gets(str);

Make_Map(str);

Find(0);

}

===============================================

全排列的算法

perm(m)为m个数r1,r2,.....rm的全排列

riperm(m-1),表示取出ri,然后对剩余的m-1个数进行全排列.

则perm(m)可表示为

r1perm(m-1),r2perm(m-1),...rmperm(m-1)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐