找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 910|回复: 7

[转贴]:排列组合

[复制链接]

已领礼包: 593个

财富等级: 财运亨通

发表于 2004-2-1 22:39:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
http://bbs.ee.ntu.edu.tw/boards/Programming/16/7.html
  1. [php]
  2. ;|首先寫一個函數 (interleave a xs), 把 a 給插到 xs 的所有空隙.
  3. 例如 (interleave 4 '(1 2 3))  => ((4 1 2 3) (1 4 2 3) (1 2 4 3) (1 2 3 4))
  4. Interleave 怎麼寫呢? 用這樣的遞迴關係: 把 a 插到 xs 的每一個空隙, 其實就是
  5. 把 a 個空隙, 或著把第一個空隙留給 (car xs), 把 a 往 (cdr xs)
  6. 的空隙裡面插.
  7. |;
  8. (defun interleave (a xs)
  9.   (if (null xs)
  10.     (list (list a))
  11.     (cons (cons a xs)                        ; a放第一個
  12.           (mapcar '(lambda (ys) (cons (car xs) ys)) ;把第一個留出來
  13.                   (interleave a (cdr xs)) ; 往(cdr xs)裡找空隙
  14.           )
  15.     )
  16.   )
  17. )

  18. ;|有了 interleave, 寫所有的排列 (permutation xs) 就方便了. 如果我們
  19. 已經算出了 (permutation (cdr xs)), 把 (car xs) 插到每一個空隙裡就可以了.
  20. |;
  21. (defun permutation (xs)
  22.   (if (null xs)
  23.     '(())
  24.     (apply 'append
  25.            (mapcar '(lambda (ys) (interleave (car xs) ys))
  26.                    (permutation (cdr xs))
  27.            )
  28.     )
  29.   )
  30. )
  31. [/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-2-4 23:48:09 | 显示全部楼层
写了个没用递归的.

  1. ;;;interleave
  2. ;;;没用递归
  3. ;;;(test 4 '(1 2 3))  => ((4 1 2 3) (1 4 2 3) (1 2 4 3) (1 2 3 4))
  4. (defun test(a li / j k li1)
  5.    (setq li1(mapcar '(lambda(x)(setq x li))(setq li(cons a li))) ;4个 '(4 1 2 3)
  6.          j  -1
  7.          li1(mapcar
  8.               '(lambda(x)
  9.                 (setq j(1+ j) k -1)
  10.                 (cdr(apply 'append(mapcar '(lambda(y)(if(= j(setq k(1+ k)))(list y a)(list y)))x)))
  11.                )
  12.             li1)
  13.     )
  14. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-2-5 02:56:49 | 显示全部楼层
其实。。。。考虑简单些也挺好:)

  1. ;(test 5 '(1 2 3 4)) -> ((5 1 2 3 4) (1 5 2 3 4) (1 2 5 3 4) (1 2 3 5 4) (1 2 3 4 5))
  2. (defun test (a lst)
  3.   (setq nlst (mapcar 'list lst))
  4.   (setq nlst2 (mapcar '(lambda (x) (apply 'append (subst (append x (list a)) x  nlst))) nlst)
  5.         nlst2 (cons (cons a lst) nlst2)
  6.   )
  7. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-2-7 13:28:22 | 显示全部楼层
最初由 陌生人 发布
[B]其实。。。。考虑简单些也挺好:)
[code]
;(test 5 '(1 2 3 4)) -> ((5 1 2 3 4) (1 5 2 3 4) (1 2 5 3 4) (1 2 3 5 4) (1 2 3 4 5))
(defun test (a lst)
  (setq nlst (mapcar 'list lst))
  (setq nlst2 (m... [/B]


你的方法肯定是不行的.

(test 4 '(1 2 3 4))怎么办?
a和lst可以重复.而且不一定是数字.
lst里面也可以重复
(test 4 '("A""A""B""B""C") )

所以我是根据位置来的
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-2-7 15:34:48 | 显示全部楼层
_$ (test 4 '(1 2 3 4))
((4 1 2 3 4) (1 4 2 3 4) (1 2 4 3 4) (1 2 3 4 4) (1 2 3 4 4))
不过下面的测试没通过
_$ (test 4 '("A""A""B""B""C") )
((4 "A" "A" "B" "B" "C") ("A" 4 "A" 4 "B" "B" "C") ("A" 4 "A" 4 "B" "B" "C") ("A" "A" "B" 4 "B" 4 "C") ("A" "A" "B" 4 "B" 4 "C") ("A" "A" "B" "B" "C" 4))

哈哈,其实上面这个只是适用与元素都不相同的情况。subst就是有这个坏毛病,大家记住啦!不过,也不是不能用啊。不同的时候还是挺多的。
如果要适用性好的。很easy。

  1. (defun test (a lst / nlst nlst2)
  2.   (setq nlst (mapcar '(lambda (x)  lst )lst) n -1)
  3.   (setq nlst2 (mapcar '(lambda (x)
  4.                          (setq n (1+ n) m -1)
  5.                          (apply 'append (mapcar '(lambda (y) (setq m (1+ m)) (if (= n m) (list y a) (list y))) x))
  6.                          )
  7.                       nlst))
  8.   (cons (cons a lst) nlst2)
  9. )

一?写完后发现和版主的好相像哦。呵,纯属巧合
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-2-7 16:34:27 | 显示全部楼层
最初由 陌生人 发布
[B]_$ (test 4 '(1 2 3 4))
((4 1 2 3 4) (1 4 2 3 4) (1 2 4 3 4) (1 2 3 4 4) (1 2 3 4 4))
不过下面的测试没通过
_$ (test 4 '("A""A""B""B""C") )
((4 "A" "A" "B" "B" "C") ("A" 4 "A" 4 "B" "B" "C") ("A" 4 ... [/B]


你的和我上面是一样的

看我的:

  1. (defun test(a li / li2)
  2. (mapcar '(lambda(x)(setq li2(append li2(list(car li)))li(cdr li))
  3.             (cdr(append li2(list a)li))
  4.           ) (setq li(cons a li)))
  5. )

现在简单了吧
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-2-7 22:03:47 | 显示全部楼层
不错不错,这个方法巧妙
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-2-7 22:26:58 | 显示全部楼层
我等只会用最简单函数的写法:

(defun tst(a lst / lst1 lst2)
  (repeat (1+ (length lst))
    (setq lst2 (cons (append lst1 (List a) lst) lst2)
          lst1 (append lst1 (list (car lst)))
          lst (cdr lst))
  )
  (reverse lst2)
)

还是aeo的好。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-16 16:26 , Processed in 0.225216 second(s), 45 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表