输入一个字符串,输出字符串的全排列。解释回溯法

jingyuge 2008-11-03 05:19:00
#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++;
}
n=0;
for (i=0;i<256;i++)
if (s[i])
{
map[n]=i;
count[n]=s[i];
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++)
if (count[i])
{
stack[depth]=i;
count[i]--;
Find(depth+1);
count[i]++;
}
}
}

main()
{
char str[1000];
gets(str);
Make_Map(str);
Find(0);
}


这句
//{putchar(map[stack[i]]);
while(*str)
{
s[*str]++;
str++;
} 是什么意思,我怎么看不懂。还有谁能简单的说一下回溯法全排列的时候是怎么实现的。
...全文
803 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
太乙 2008-11-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 vk2211 的回复:]
如果遇到A,s[*str]++表示s[65]++,遇到B,则s['B']++
最终,s['A'],s['B'],s['C']...的值就是A、B、……这些字母出现的次数
[/Quote]

也就这个意思~~~~

lz再想想~~
piaomiaoju 2008-11-06
  • 打赏
  • 举报
回复
#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[n]=i; //n记录了字符种类数,map[n]记录了原来*str的值.
count[n]=s[i]; //count[n]记录每种字符的个数
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)
pingzi_1119 2008-11-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 vk2211 的回复:]
如果遇到A,s[*str]++表示s[65]++,遇到B,则s['B']++
最终,s['A'],s['B'],s['C']...的值就是A、B、……这些字母出现的次数
[/Quote]
up
shinefree2004 2008-11-06
  • 打赏
  • 举报
回复
占个地方
cnn_505 2008-11-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 vk2211 的回复:]
如果遇到A,s[*str]++表示s[65]++,遇到B,则s['B']++
最终,s['A'],s['B'],s['C']...的值就是A、B、……这些字母出现的次数
[/Quote]

up
xiaoliang_c 2008-11-06
  • 打赏
  • 举报
回复
UP
zapdos 2008-11-06
  • 打赏
  • 举报
回复
count[i]的++--似乎就是一个装饰...
e_sharp 2008-11-05
  • 打赏
  • 举报
回复
UP
zhanglian1126 2008-11-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 Chiyer 的回复:]
http://dev.csdn.net/author/fancyerII/b73504e30685413ea81574d703ebb700.html
[/Quote]
^^^^蛮好
帅得不敢出门 2008-11-03
  • 打赏
  • 举报
回复
回溯法 名词解释
http://baike.baidu.com/view/45.htm
星羽 2008-11-03
  • 打赏
  • 举报
回复
up
vk2211 2008-11-03
  • 打赏
  • 举报
回复
如果遇到A,s[*str]++表示s[65]++,遇到B,则s['B']++
最终,s['A'],s['B'],s['C']...的值就是A、B、……这些字母出现的次数

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧