明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: chlh_jd

lisp应用递归算法10题

    [复制链接]
 楼主| 发表于 2010-9-1 23:47 | 显示全部楼层
公布“伪答案”的时间还没到啊,大家多SHOW点吧
 楼主| 发表于 2010-9-1 23:55 | 显示全部楼层
题目9:编写一个递归函数,用新元素new替换表lst中第i项元素,这里i = 0 1 2 3 ...
我把QJ-CHEN老师的源码延伸了下,改为支持2重表,方便诸如矩阵列表使用
  1. ;;;by GSLS(SS)
  2. ;;;(ch-lst 4 '(2 2) '((1 2 3) (2 4 5) (3 5 6)))返回((1 2 3) (2 4 4) (3 5 6))
  3. (defun ch-lst (new i lst / j)
  4.   (if (null lst)
  5.     (*error* "No list")
  6.     (if (numberp i)
  7.       (cond ((zerop i)
  8.       (cons new (cdr lst))
  9.      )
  10.      ((> i 1)
  11.       (cons
  12.         (car lst)
  13.         (ch-lst   new  (1- i)  (cdr lst))
  14.       )
  15.      )
  16.      (T lst)
  17.       )
  18.       (progn
  19. (setq j (cadr i) ;_这里您可以不定义局部变量j,和重定义i,但效率将较低
  20.        i (car i)
  21. )
  22. (if j
  23.    (ch-lst (ch-lst new j (nth i lst)) i lst)
  24.    (ch-lst new i lst)
  25. )
  26.       )
  27.     )
  28.   )
  29. )

评分

参与人数 1威望 +1 明经币 +1 金钱 +30 贡献 +30 激情 +30 收起 理由
highflybir + 1 + 1 + 30 + 30 + 30 【好评】好程序

查看全部评分

 楼主| 发表于 2010-9-10 20:44 | 显示全部楼层
素数判断,我是这样写的
  1. (defun is-prime (n)
  2.   (defun is-prime-helper (n try)
  3.     (if (= n try)
  4.       T
  5.       (if (zerop (rem n try))
  6. nil
  7. (is-prime-helper n (+ try 1))
  8.       )
  9.     )
  10.   )
  11.   (is-prime-helper n 2)
  12. )

评分

参与人数 1威望 +1 明经币 +1 金钱 +30 贡献 +30 激情 +30 收起 理由
highflybir + 1 + 1 + 30 + 30 + 30 【好评】好程序

查看全部评分

发表于 2010-9-12 09:12 | 显示全部楼层
就是说,假如不定义一个其他函数,就is-prime 本身还是无法递归的:)
 楼主| 发表于 2010-9-19 17:28 | 显示全部楼层

同意qj-chen老师的观点,is-prime不定义局部函数,本身是无法递归的

 楼主| 发表于 2010-9-19 17:34 | 显示全部楼层
第7题powerset递归函数我是这样写的
  1. ;;;列出表中元素所有可能组合,包括空集,按先后顺序
  2. ;;;(powerset (list 1 2 3)) 返回 ((1 2 3) (1 2) (1 3) (1) (2 3) (2) (3) nil)
  3. (defun powerset (lst)
  4.   (if (null lst)
  5.     (list nil)
  6.     (append ;_这里的append可以采用自定义myappend函数
  7.       (mapcar '(lambda (x) ;_这里的mapcar可以采用qj-chen老师写的自定义mymapcar函数,lamda可以采用defun定义局部函数
  8.    (cons (car lst) x)
  9.         )
  10.        (powerset (cdr lst))
  11.       )
  12.       (powerset (cdr lst))
  13.     )
  14.   )
  15. )
 楼主| 发表于 2010-9-19 17:44 | 显示全部楼层
7a这道题目有点难,牵涉到时间测试,这里先提供一个简易时间测试函数(或许您有更好的,权当献丑吧^_^)
  1. ;;;小函数测试时间,ti为使用次数,funname为函数名,funarglist为函数funname的参数列表
  2. ;;;如(powerset (list 1 2 3))测试100000次运行时间使用代码为
  3. ;;;    (times 100000 'powerset (list (list 1 2 3)))
  4. (defun times (ti funname funarglist / t1 t2)
  5.   (setq t1 (getvar "date"))
  6.   (repeat ti
  7.     (vl-catch-all-apply
  8.       funname
  9.       funarglist
  10.     )
  11.   )
  12.   (setq t2 (getvar "date"))
  13.   (princ "函数:")
  14.   (princ funname)
  15.   (princ (strcat "运行" (rtos ti 2 0) "次" ))
  16.   (princ "测试结果")
  17.   (princ (menucmd (strcat "M=$(edtime,"
  18.      (rtos (- t2 t1) 2 16)
  19.      ",HH:MM:SS:MSEC)"
  20.     )
  21.   )
  22.   )
  23. )
发表于 2010-9-19 19:53 | 显示全部楼层
:) 谢谢chlh_jd的组合函数,写的很简洁
 楼主| 发表于 2010-9-21 20:36 | 显示全部楼层
7a编写一个faster-powerset 递归函数,效率比正向排序高一倍;大家测试下列代码,看看有没有更好的写法
  1. ;;;by GSLS(SS)
  2. ;;;(faster-powerset (list 1 2 3))
  3. (defun faster-powerset (lst)
  4.   (defun faster-powerset-helper (p lst)
  5.     (if (null lst)
  6.       p
  7.       (faster-powerset-helper
  8. (append
  9.    (mapcar '(lambda (x)
  10.        (cons (car lst) x)
  11.      )
  12.     p
  13.    )
  14.    p
  15. )
  16. (cdr lst)
  17.       )
  18.     )
  19.   )
  20.   (faster-powerset-helper (list nil) lst)
  21. )
 楼主| 发表于 2010-9-25 22:54 | 显示全部楼层
第10题,find-matching-pair里面用到了适应函数TEST,在递归里面引用函数名一般是不需要加上quote的,有2种写法分别如下:

方法一,使用nth函数
  1. ;;;
  2. ;;;
  3. ;|测试1
  4. (find-matching-pair = (list 1 2 3 4 5 7 8 1 2))
  5. |;
  6. ;|测试2
  7. (find-matching-pair
  8.   (lambda (a b) (= a (* b 2)))
  9.   (list 1 2 3 4 5 7 8 1 2)
  10. )|;
  11. (defun find-matching-pair (test lst / find-matching-pair-helper)
  12.   (defun find-matching-pair-helper (test lst i j)
  13.     (if (= i (length lst))
  14.       (princ "no matching pair found")
  15.       (if (= j (length lst))
  16. (find-matching-pair-helper test lst (+ i 1) 0)
  17. (if (and (/= i j)
  18.    (test (nth i lst)
  19.          (nth j lst)
  20.    )
  21.      )
  22.    (cons (nth i lst) (nth j lst))
  23.    (find-matching-pair-helper test lst i (+ j 1))
  24. )
  25.       )
  26.     )
  27.   )
  28.   (find-matching-pair-helper test lst 0 0)
  29. )

方法二、使用前面写过的remove-nth
  1. (defun find-matching-pair (test lst)
  2.   (defun find-matching-pair-helper (test orig left others)
  3.     (if (null left)
  4.       (princ "no matching pair found")
  5.       (if (null others)
  6. (if (null (cdr left))
  7.    (princ "no matching pair found")
  8.    (find-matching-pair-helper
  9.      test
  10.      orig
  11.      (cdr left)
  12.      (remove-nth
  13.        (- (length orig)
  14.    (length (cdr left))
  15.        )
  16.        orig
  17.      )
  18.    )
  19. )
  20. (if (test (car left) (car others))
  21.    (cons (car left) (car others))
  22.    (find-matching-pair-helper test orig left (cdr others))
  23. )
  24.       )
  25.     )
  26.   )
  27.   (find-matching-pair-helper test lst lst (cdr lst))
  28. )
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-3 21:07 , Processed in 0.173556 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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