[ML][练习] 生成排列
来源:《ML 程序设计教程》3.13 求后继排列的问题
此例子使用的算法描述见:[Generate Permutation].
操作大致分三步:
- 搜索,分段
- 搜索,交换
- 逆转
以前用 C 实现过,数据结构为数组。逆转可以通过两个指针(一头一尾)进行交换。用 ML 实现时,使用了列表,在第一步时,通过列表的积累操作,已经把改逆转的逆转掉了。
另外,为了便于列表操作。在 ML 实现中,[4,3,2,1] 是 4 排列中最小的,而 [1,2,3,4] 是最大的。即左边看成低位,而右边看成高位。
[ 本帖最后由 win_hate 于 2008-11-15 14:57 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
应该不是 “N 进制的 ++ 问题”,因为元素不可以重复。
比如,只用 12345 五个数字,12345 的下一个应该是 12354 ,而不能是 12351 .
取第 n 个,这个思想我也很喜欢,曾经用 c 写过一个取第 n 个组合的程序,现在还经常用得到,就是给一组数,直接到到第 n 个组合。
你这个算法太深奥了,
是不是说白了就是 12345 的下一个就是 12346 这样子?
假设有 N 个不重复的元素,那么就是 N 进制 ++ 的问题?
haskell 那个我是这样测的(帮忙看看是否用错了命令):
复制代码
用 ML 的代码如下:
复制代码
Haskell 那个取第一万个, ML 这个取第十万个。ML 这个也能马上算出。
[ 本帖最后由 win_hate 于 2008-11-17 13:32 编辑 ]
MMMIX 的程序在严格求值的语言中,只能对付很小的 n。因为该程序本质上生成全部的,也就是 n! 个排列。
我的那个程序本意不是生成排列全体,而是给定一个排列后,生成其后继排列。
但是,在惰性环境中,MMMIX 的程序可以对付很大的 n,而且性能还不错。这个有点出乎我的意料,看来惰性求值真是个好东西。
不过,从算法上看,生成后继排列的算法仍然占优。我简单测试了一下,用 n=10000,取产生序列中的第 10000 个排列。用顶楼的算法可以马上算出。用生成全部排列那个我没等它算完,内存已经涨得很厉害了。
生成后继排列的算法时间,空间复杂度都是 O(n), MMMIX 那个空间占得厉害。
[ 本帖最后由 win_hate 于 2008-11-17 13:30 编辑 ]
对研究算法来说也许是这样,但对于编程语言本身来说,提供好的(也即易学易用的)语法是非常重要的。
不要太在意语法糖,那些都是浮云,关键是思想。
MMMIX 用 Haskell 写的版本要简单很多,呵呵
复制代码
复制代码