明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: lanjqka

[讨论] 学习 lisp 递归

[复制链接]
 楼主| 发表于 2014-1-20 14:56:24 | 显示全部楼层
  1. ;|
  2. _$$$$$$$$ (3dp->2dp '(0 1 2))
  3. (0 1)
  4. |;
  5. (defun 3dp->2dp (plst)
  6.   (if (null (cadr plst))
  7.     nil
  8.     (list (car plst) (cadr plst))
  9.   )
  10. )

  11. ;|
  12. _$$$$$$$$ (3dpl->2dpl '((0 1 2)(3 4 5)(6 7 8)))
  13. ((0 1) (3 4) (6 7))
  14. |;
  15. (defun 3dpl->2dpl (plst) (mapcar '3dp->2dp plst))
  16. (defun 3dpl->2dpl2 (plst)
  17.   (if (null plst)
  18.     nil
  19.     (cons (3dp->2dp (car plst)) (3dpl->2dpl2 (cdr plst)))
  20.   )
  21. )

  22. ;| 简单比对一下 3dpl->2dpl 与 3dpl->2dpl2 运行时间 相差不大
  23. _$$$$$$$$ (calrpt 100000 '3DPL->2DPL2)
  24. (repeat 100000 (3DPL->2DPL2 'arglst))
  25. 运行时间: 0.639988 s.
  26. _$$$$$$$$ (calrpt 100000 '3DPL->2DPL)
  27. (repeat 100000 (3DPL->2DPL 'arglst))
  28. 运行时间: 0.670002 s.
  29. _$$$$$$$$ (calrpt 1000000 '3DPL->2DPL2)
  30. (repeat 1000000 (3DPL->2DPL2 'arglst))
  31. 运行时间: 6.364 s.
  32. _$$$$$$$$ (calrpt 1000000 '3DPL->2DPL)
  33. (repeat 1000000 (3DPL->2DPL 'arglst))
  34. 运行时间: 6.39602 s.
  35. |;

  36. ;|
  37. _$$$$$$$$ (-sub-cons-s '(0 1 2 3 4 5 6) 3)
  38. ((0 1 2) (3 4 5))
  39. |;
  40. (defun -sub-cons-s (lst n)
  41.   (if (null lst)
  42.     nil
  43.     (if (< (length lst) n)
  44.       nil
  45.       (cons (ntha n lst) (-sub-cons-s (nthbc n lst) n))
  46.     )
  47.   )
  48. )

  49. ;|
  50. _$$$$$$$$ (consn 10)
  51. (0 1 2 3 4 5 6 7 8 9 10)
  52. |;
  53. (defun consn (i)
  54.   (if (< i 0)
  55.     nil
  56.     (append (consn (- i 1)) (list i))
  57.   )
  58. )

  59. (defun calrpt (n fun / tst tend)
  60.   (setq arglist (-sub-cons-s (consn 1001) 3))
  61.   (setq tst (getvar "DATE"))
  62.   (repeat n (vl-catch-all-apply fun arglst))
  63.   (setq tend (getvar "DATE"))
  64.   (mapcar 'princ
  65.           (list "(repeat "
  66.                 n
  67.                 " ("
  68.                 fun
  69.                 " '"
  70.                 "arglst"
  71.                 "))"
  72.                 "\n运行时间: "
  73.                 (* (- tend tst) 86400.0)
  74.                 " s.\n"
  75.           )
  76.   )
  77.   (princ)
  78. )
 楼主| 发表于 2014-1-21 13:39:03 | 显示全部楼层
  1. ;|
  2. _$$ (cons0 10)
  3. (1 0 0 0 0 0 0 0 0 0 0)
  4. |;
  5. (defun cons0 (i)
  6.   (if (zerop i)
  7.     (list 1)
  8.     (append (cons0 (- i 1)) (list 0))
  9.   )
  10. )

  11. ;|
  12. _$$ (Divide (cons0 100) 997)
  13. (0 1003 9027 81243 731193 580742 ...
  14. |;
  15. (defun Divide (xlist d / n v r g a)
  16.   (setq n 0
  17.         r 0
  18.         a nil
  19.   )
  20.   (repeat (length xlist)
  21.     (setq v (+ (nth n xlist) (* r 1000000)))
  22.     (setq g (/ v d))
  23.     (setq r (rem v d))
  24.     (setq a (append a (list g)))
  25.     (setq n (1+ n))
  26.   )
  27.   a
  28. )

  29. ;|
  30. _$$ (div! 1 997 600)
  31. (0 1003 9027 81243 731193 580742 ...
  32. |;
  33. (defun div! (n d i / j k)
  34. ;|(setq k (ascii "+"))
  35.   (defun f1 (str)
  36.     (if (= (ascii str) k)
  37.       (substr str 2)
  38.       (f1 (substr str 2))
  39.     )
  40.   )
  41.   (setq j (atoi (f1 (rtos (/ (expt 2 30) d) 1 0))))
  42.   |;
  43.   (setq j 6)
  44.   (defun f3 (n i)
  45.     (if (zerop i)
  46.       nil
  47.       (cons (/ n d) (f3 (* (rem n d) (expt 10 j)) (- i 1)))
  48.     )
  49.   )
  50.   (f3 n (+ (fix (/ i j)) 2))
  51. )

  52. ;| 1/997 = 0.001003009027...
  53. _$$ (calrpt 100000 'Divide '((1 0 0 0 0 0 0 0 0 0 0) 997))
  54. (repeat 100000 (DIVIDE '((1 0 0 0 0 0 0 0 0 0 0) 997)))
  55. 运行时间: 2.762 s.
  56. 单次运行结果:(0 1003 9027 81243 731193 580742 226680 40120 361083 249749 247743)
  57. _$$ (calrpt 100000 'div! '(1 997 55))
  58. (repeat 100000 (DIV! '(1 997 55)))
  59. 运行时间: 1.52898 s.
  60. 单次运行结果:(0 1003 9027 81243 731193 580742 226680 40120 361083 249749 247743)
  61. _$$ (calrpt 10000 'Divide (list cons0100 997))
  62. (repeat 10000 (DIVIDE '((1 0 0 0 0 0 0 0 0 0 0 ...
  63. 运行时间: 3.541 s.
  64. 单次运行结果:(0 1003 9027 81243 731193 ...
  65. _$$ (calrpt 10000 'div! '(1 997 600))
  66. (repeat 10000 (DIV! '(1 997 600)))
  67. 运行时间: 1.12299 s.
  68. 单次运行结果:(0 1003 9027 81243 731193 ...
  69. |;
  70. (defun calrpt (n fun arglst / tst tend)  
  71.   (setq tst (getvar "DATE"))
  72.   (repeat n (vl-catch-all-apply fun arglst))
  73.   (setq tend (getvar "DATE"))
  74.   (mapcar 'princ
  75.           (list "(repeat "
  76.                 n
  77.                 " ("
  78.                 fun
  79.                 " '"
  80.                 arglst
  81.                 "))"
  82.                 "\n运行时间: "
  83.                 (* (- tend tst) 86400.0)
  84.                 " s.\n单次运行结果:"
  85.           )
  86.   )
  87.   (princ (vl-catch-all-apply fun arglst))
  88.   (princ)
  89. )
 楼主| 发表于 2014-1-21 13:48:54 | 显示全部楼层
本帖最后由 lanjqka 于 2014-1-21 13:50 编辑

上面的例子
计算1/997高精度结果
对长表进行循环处理 的时间要比 用递归构造长表 的时间 多
特别是表比较长时
发表于 2014-1-30 18:37:17 | 显示全部楼层
本帖最后由 q3_2006 于 2014-1-31 07:27 编辑
lanjqka 发表于 2014-1-21 13:48
上面的例子
计算1/997高精度结果
对长表进行循环处理 的时间要比 用递归构造长表 的时间 多


"1.1.1.1"
返回("1.1" "0.1" "0.1")用递归怎么写??拜托指点下,谢谢!

(defun sstr (str n)
(if (= n 0)
    nil
    (cons (rtos (atof str)) (sstr (substr str (1+ (strlen (rtos (atof str))))) (1- n)))
  )
)
(sstr str 3)-->>("1.1" "0.1" "1")
为什么这样....不知道原因呀...???
 楼主| 发表于 2014-2-11 13:33:41 | 显示全部楼层
q3_2006 发表于 2014-1-30 18:37
"1.1.1.1"
返回("1.1" "0.1" "0.1")用递归怎么写??拜托指点下,谢谢!

是不是这样 在首字符为"."时加一个前导0
  1. ;|
  2. _$$ (sstr "1.1 .1 .1")
  3. ("1.1" "0.1" "0.1")
  4. |;
  5. (defun sstr (str / n)
  6.   (setq str (vl-string-trim " " str))
  7.   (if (= (ascii str) (ascii "."))
  8.     (setq str (strcat "0" str))
  9.   )
  10.   (setq n (vl-string-search " " str))
  11.   (if (= str "")
  12.     nil
  13.     (cons (substr str 1 n) (if n (sstr (substr str (+ n 1)))))
  14.   )
  15. )
发表于 2014-2-11 14:11:51 | 显示全部楼层
lanjqka 发表于 2014-2-11 13:33
是不是这样 在首字符为"."时加一个前导0

是的是的。。。。谢谢指导!
发表于 2014-2-11 14:13:51 | 显示全部楼层
lanjqka 发表于 2014-2-11 13:33
是不是这样 在首字符为"."时加一个前导0

也不对。。。。.1前面没有空格的。。。。是拆分数字问题。。。
 楼主| 发表于 2014-2-11 16:30:28 | 显示全部楼层
本帖最后由 lanjqka 于 2014-2-11 16:34 编辑

应该是 rtos 的原因
(rtos number [mode [precision]])
  1. ;|
  2. _$$$$ (sstr "1.1.1.1" 3)
  3. ("1.1" "0.1" "0.1")
  4. |;
  5. (defun sstr (str n / tmp)
  6.   (if (zerop n)
  7.     nil
  8.     (append (list (setq tmp (rtos (atof str) 2 1)))
  9.           (sstr (strcat "0" (substr str (+ (strlen tmp) 1))) (- n 1))
  10.     )
  11.   )
  12. )
 楼主| 发表于 2014-2-11 17:01:20 | 显示全部楼层
q3_2006 发表于 2014-2-11 14:13
也不对。。。。.1前面没有空格的。。。。是拆分数字问题。。。
  1. ;|
  2. _$$ (sstr "1.1.1.1")
  3. ("1.1" "0.1" "0.1")
  4. |;
  5. (defun sstr (str / n)
  6.   (setq str (vl-string-trim " " str))
  7.   (if (= (ascii str) (ascii "."))
  8.     (setq str (strcat "0" str))
  9.   )
  10.   (setq n (vl-string-search "." str 2))
  11.   (if (= str "")
  12.     nil
  13.     (cons (substr str 1 n) (if n (sstr (substr str (+ n 1)))))
  14.   )
  15. )
发表于 2014-2-11 17:11:49 | 显示全部楼层
lanjqka 发表于 2014-2-11 17:01

就是这个了。。。谢谢。。。脑子笨,感觉还是很难。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-22 21:00 , Processed in 0.192323 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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