Fantasy Soft
posts - 256, comments - 1319, trackbacks - 41, articles - 8
博客园
::
首页
::
新随笔
::
联系
::
订阅
::
管理
恶补算法与数据结构(一)——排列问题
Posted on 2004-09-26 13:36
FantasySoft
阅读(1560)
评论(2)
编辑
收藏
所属分类:
All About Soft
、
Miscellaneous
上次朋友的一个问题,让我重新翻开了那本尘封已久的《数据结构、算法与应用》。仅仅重读了第一章,我不得不再次为专注数据结构与算法研究的科学家们佩服得五体投地。
让我佩服的问题其实很简单:生成一个list中的元素的全排列,也就是说input为:[a, b, c],output则是[abc, acb, bac, bca, cab, cba],当然list中的元素个数是不定的。是不是很简单的问题呢?不过比较愚钝的我,却没有办法想出问题的答案,尽管我知道应该使用递归来实现。
想不出来就只好看书上是怎么实现的了。基于递归的算法,通常都需要一个递归等式(recursive component,递归部分)和一个递归终结的条件(base,基本部分)。那么对于以上的问题,递归部分和基本部分都是什么呢?假设递归函数为Perm(E),E为元素的集合,那么基本部分是比较容易想到的,就是当集合E中只有一个元素的时候,Perm(E) = e,e为集合E中唯一的元素;接下来的就是递归部分了,当集合E中的元素个数大于1的时候,那么:Perm(E) = e
1
.Perm(E
1
)+e
2
.Perm(E
2
)+e
3
.Perm(E
3
)...+e
n
.Perm(E
n
),E = e
1
+ E
1
= e
2
+ E
2
= e
3
+ E
3
= e
n
+ E
n
。也就是说,e
n
.Perm(E
n
)表示从集合E中取出一个元素e
n
,然后将剩下的元素进行排列,两者再相连就得到了以e
n
元素作为前缀的所有排列了,那么将集合E中的所有元素遍历一次,得到以每一个元素作为前缀的排列,最后就可以得到所有的排列方式了。至此,递归函数所需要的两个必要部分都清楚了,那么代码该如何实现呢?以下是书上给出的代码:
template
<
class
T
>
void
Perm(T list[],
int
k,
int
m)
//m为list数组index的最大值,而k则表示
position,初始值为0
{
int
i;
if
(k
==
m)
{
for
(i
=
0
; i
<=
m; i
++
)
cout
<<
list[i];
cout
<<
endl;
}
else
for
(i
=
k; i
<=
m; i
++
)
{
Swap(list[k], list[i]);
//
通过交换,使得每个元素都能够成为前缀
Perm(list, k
+
1
, m);
//
递归调用,得到作为后缀的元素的所有排列
Swap(list[k], list[i]);
}
}
Swap是一个自定义的inline函数,用作交换两个元素。尽管这样的代码很简洁,但是总觉得不是太爽了,毕竟有那么多的参数,而且似乎与算法中描述的不太像。大家再看一下python的实现:
def permute(seq):
l
=
len(seq)
if
l
==
1
:
return
[seq]
else
:
res
=
[]
for
i
in
range(len(seq)):
rest
=
seq[:i]
+
seq[i
+
1
:]
for
x
in
permute(rest):
res.append(seq[i:i
+
1
]
+
x)
return
res
是不是会更为简洁,更容易理解,而且更符合算法的描述呢?在以上代码中,rest变量对应着取出元素i剩下的集合,for x in permute(rest)遍历集合rest产生的所有的排列,然后通过seq[i:i+1] + x 就可以得到以元素i作为前缀的排列了。当然这样的算法有明显的一个问题是,占用了较大的空间。因为当len(seq)>1的时候,每次函数的调用,都必须为res开辟新的空间,一旦递归嵌套的层次比较多,则需要比较大的空间了。
排列的问题解决了,接着就是组合问题(外延则是集合的子集问题)了。或许太长时间没有去思考算法与数据结构的问题了,这个问题仍然让我无从下手。对算法与数据结构有心得的朋友多多指教了。//Bow
Feedback
#1楼
回复
引用
2004-09-27 09:31 by
saierdia [未注册用户]
stl里的next_permutation,prev_permutation 已经实现排列功能了。
#2楼
[
楼主
]
回复
引用
查看
2004-09-27 09:42 by
FantasySoft
在实际应用当中,确实是应该使用STL中的实现,毕竟自己的实现是很难跟STL相媲美的。作为学习,不管有多丑陋,还是得自己写写的,呵呵~~~
社区
新闻
新用户注册
刷新评论列表
标题
姓名
主页
Email
(只有博主才能看到)
验证码
*
看不清,换一张
[
登录
][
注册
]
内容(请不要发表任何与政治相关的内容)
Remember Me?
登录
使用高级评论
新用户注册
返回页首
恢复上次提交
[使用Ctrl+Enter键可以直接提交]
该文被作者在 2005-09-21 15:06 编辑过
另存
打印
所属分类的其他文章:
·
草根化进程
·
若干域名赠送并结识各路英雄
·
压箱底的几个域名出售
·
重新定义旅游网站,米胖新版发布
·
有关核心竞争力
·
DreamHost优惠码——PERHAPS
·
若干域名转让
·
不谈模式,只谈实现
·
一切变得越来越有趣了
·
《WebWork in Action》中文版终于如期面市了
最新IT新闻:
·
金山:360的免费杀毒只能是短期行为
·
江民科技回应杀毒软件免费说 没病不能乱吃药
·
WCG2008中国区总决赛打响
·
新型的编程语言:eC
·
免费的BitDefender能复制卡巴斯基的成功吗?
博客园新闻频道
博客园首页
社区
Powered by:
博客园
Copyright © FantasySoft
日历
<
2004年9月
>
日
一
二
三
四
五
六
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
公告
阅读我的译作《WebWork in Action》中文版:
CSDN读书频道
电子工业出版社
China-pub
与我互动
给我发短消息
常用链接
我的随笔
我的空间
我的短信
我的评论
更多链接
我的参与
我的新闻
最新评论
我的标签
留言簿
(52)
给我留言
查看私人留言
我参与的团队
Design & Pattern团队(0/813)
广州.NET俱乐部(0/1693)
小蟒蛇IronPython (0/67)
MVP团队(0/498)
随笔分类
All About Fantasy(83)
All About Soft(173)
Bright Wiki(3)
Daily Portal(3)
Elegant Python(12)
Excellent WebWork(13)
Exciting Linux(2)
Lovely DotNet(12)
Miscellaneous(21)
Non Tech.(4)
Only Windows (12)
Practical Java(8)
Pure C++(9)
Sharp IronPython(29)
Thought Ware(50)
随笔档案
2008年7月 (1)
2008年6月 (1)
2008年4月 (1)
2008年3月 (1)
2008年1月 (1)
2007年12月 (1)
2007年11月 (1)
2007年10月 (1)
2007年7月 (1)
2007年6月 (3)
2007年5月 (1)
2007年4月 (5)
2007年3月 (3)
2007年2月 (2)
2007年1月 (2)
2006年12月 (2)
2006年11月 (3)
2006年10月 (2)
2006年9月 (6)
2006年8月 (5)
2006年7月 (10)
2006年6月 (6)
2006年5月 (7)
2006年4月 (2)
2006年3月 (3)
2006年2月 (3)
2006年1月 (5)
2005年12月 (5)
2005年11月 (6)
2005年10月 (5)
2005年9月 (11)
2005年8月 (15)
2005年7月 (14)
2005年6月 (6)
2005年5月 (2)
2005年4月 (4)
2005年3月 (2)
2005年2月 (13)
2005年1月 (4)
2004年12月 (4)
2004年11月 (1)
2004年10月 (9)
2004年9月 (29)
2004年8月 (32)
2004年7月 (6)
2004年6月 (7)
2004年5月 (2)
文章分类
Fantasy(2)
Soft(6)
文章档案
2005年11月 (1)
2005年7月 (1)
2004年9月 (4)
2004年8月 (2)
相册
Google In Athens 2004
Google In Winter-Holiday 2005
Trip in Seattle
Experts' Links
Allen Lee's Magic
ASP.NET入门随想 - 老燕
femto的Blog
Flier's Sky
HaoHappy' Blog
HD 的 Weblog
Liki's Blog
Raimundo's Blog
Sumtec's Blog
Teddy's Knowledge Base
Terrylee的技术专栏
this.Think()
爱上写程序
编程夜未眠
透明思考
周星星 之 Blog
装配中的脑袋
琢思磋文轩
My Friends
Underneath the Banyantree
潺潺琴柔,啸啸剑狂
记忆碎片
小鱼曼曼-eely
Wonderful Links
0.英雄帝国ONLINE
1.Fantasy Soft - 另外的一个窝
A.中华维客
B.聚好吃 美食百科
C.eemap.org
D.天下维客
E.网络天书
F.维库
搜索
最新评论
1. re: 你今天Python了吗?(上)
Java提高了生产效率?
第一次听到这么说
--安眠花
2. re: 关于创业
支持楼主
--逖靖寒
3. re: 从银行ATM机取款失败说起
我是2008年7月15日厦门工商银行24小时自助银行取款的,等了很久没反映,一直显示系统正在通信中,只好按下取消键,过了一会儿之后,出现系统通信错误,钱没有出来,在另外一台取款机上查询,发现钱已从账...
--可
4. re: 关于创业
谢谢博主真诚的分享你这五年来的感受,我刚出校园,因此对我而言显得更有意义。
--Eleanor Yan
5. re: 关于创业
@坐看云起 谢谢您! 对于您的评论,我只想重申一点:放下并不是放弃。因为要定一个理想,真的太简单。想想我们儿时的理想是什么,估计做个科学家是最热门的答案了。可是到了长大之后呢? 我想,很多东西都是...
--FantasySoft
阅读排行榜
1. WebWork初体验(11898)
2. 解读Hashtable(10994)
3. 让人头痛的Vector(提问篇)(9012)
4. 有关核心竞争力(8269)
5. .NET和J2EE该相互学习什么(7336)
评论排行榜
1. 关于创业(73)
2. 吹响反击Ruby On Rails的号角(53)
3. 有关核心竞争力(51)
4. 二刻拍案惊奇之——国人为什么那么轻视技术(39)
5. .NET和J2EE该相互学习什么(37)