找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

楼主: Lispboy

[] 返回表第N个元素之后的所有元素(不包括N)

[复制链接]

已领礼包: 6468个

财富等级: 富甲天下

发表于 2013-6-13 02:40:01 | 显示全部楼层
确实有些复杂,用个cdr就可以了。

点评

复杂自有复杂的道理,确定看懂了代码了吗?  详情 回复 发表于 2013-6-13 02:42
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

 楼主| 发表于 2013-6-13 02:42:11 | 显示全部楼层
sicky111 发表于 2013-6-13 02:40
确实有些复杂,用个cdr就可以了。

复杂自有复杂的道理,确定看懂了代码了吗?

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

使用道具 举报

发表于 2013-6-13 09:49:18 | 显示全部楼层
本帖最后由 wowan1314 于 2013-6-13 09:50 编辑
Free-Lancer 发表于 2013-6-12 23:33
经测试,分治算法确实可以提高效率,不过差在毫秒级

不知道用满足条件就退出循环的mapcar方法比楼主的函数会不会更优秀?!
  1. ;;=============={ 返回表第N个元素之后的所有元素 }===================
  2. ;;测试: (T33 3  '(2334 556 33 44 66 77 22))==> (44 66 77 22)
  3. (DEFUN T33 (n LST / A)
  4.   (setq A 0)
  5.   (vl-catch-all-apply
  6.     'mapcar
  7.     (LIST '(lambda (x)
  8.        (SETQ A (1+ A))
  9.        (if (< N A)
  10.          (EXIT)
  11.          (setq lst (cdr lst))
  12.        )
  13.      )
  14.     lst
  15.     )
  16.   )
  17.   lst
  18. )

点评

其实,你可以改造下,也分两个分支做,大于1/2用一个MAPCAR, 小于1/2 用另外一个MAPCAR,那样肯定你的快。 不过,我一见到程序里面有(EXIT)就感觉不好,个人原因。  详情 回复 发表于 2013-6-13 10:08
葛老,测试是你的强项,你测试下,找个100万的表。 我猜,如果你要找99万以后的表,肯定是我的快  详情 回复 发表于 2013-6-13 10:03

评分

参与人数 1D豆 +5 收起 理由
Lispboy + 5 技术引导讨论和指点奖!

查看全部评分

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

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

 楼主| 发表于 2013-6-13 10:03:47 | 显示全部楼层
wowan1314 发表于 2013-6-13 09:49
不知道用满足条件就退出循环的mapcar方法比楼主的函数会不会更优秀?!

葛老,测试是你的强项,你测试下,找个100万的表。

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

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

 楼主| 发表于 2013-6-13 10:08:13 | 显示全部楼层
wowan1314 发表于 2013-6-13 09:49
不知道用满足条件就退出循环的mapcar方法比楼主的函数会不会更优秀?!

其实,你可以改造下,也分两个分支做,大于1/2用一个MAPCAR, 小于1/2 用另外一个MAPCAR,那样肯定你的快。

不过,我一见到程序里面有(EXIT)就感觉不好,个人原因。

点评

用cond分支的话,就跟你的函数一样了,得用一堆代码。  发表于 2013-6-13 13:41
返回表第N个元素之后的所有元素的算法和删除表第N个元素的算法基本差不多,删除表第N个元素的最快算[/url=http://bbs.mjtd.com/thread-90335-1-1.html]法曾经在明经论坛有过大讨论,集成了很多优秀算法代码,大家可  详情 回复 发表于 2013-6-13 10:16
那就用(quit)呵呵!  发表于 2013-6-13 10:15
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-6-13 10:16:08 | 显示全部楼层
Lispboy 发表于 2013-6-13 10:08
其实,你可以改造下,也分两个分支做,大于1/2用一个MAPCAR, 小于1/2 用另外一个MAPCAR,那样肯定你的快 ...

返回表第N个元素之后的所有元素的算法和删除表第N个元素的算法基本差不多,删除表第N个元素的最快算法曾经在明经论坛有过大讨论,集成了很多优秀算法代码,大家可以去看看!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6530个

财富等级: 富甲天下

发表于 2013-6-13 10:50:05 | 显示全部楼层
Lispboy 发表于 2013-6-13 10:08
其实,你可以改造下,也分两个分支做,大于1/2用一个MAPCAR, 小于1/2 用另外一个MAPCAR,那样肯定你的快 ...

其实不要太过纠结于repeat、append、mapcar、cons等函数的效率。
就如本例,repeat可能是最直观的,在n大约一半表长的时候,的确循环的次数太多,那么就reverse?肯定错了,reverse的效率如何?再构建列表的效率如何?
mapcar似乎公认是最有效率的循环,但如果加一个判断情况又如何?
每个函数都有自己的最佳使用范围,如果使用不当,函数本身再有效率也是徒然。

点评

长老说的对! 加if判断后,速度有点影响,不如vl-member-if函数了  详情 回复 发表于 2013-6-13 19:58
测试过 10W 的表,Reverse 的效率是高的  详情 回复 发表于 2013-6-13 11:41
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-13 11:41:13 | 显示全部楼层
ll_j 发表于 2013-6-13 10:50
其实不要太过纠结于repeat、append、mapcar、cons等函数的效率。
就如本例,repeat可能是最直观的,在n ...

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

使用道具 举报

发表于 2013-6-13 15:33:51 | 显示全部楼层
测了下,数据90W的整数表!
参与测试的函数:VL-member及另类mapcar.与楼主的函数。
  1. (defun C:1 ()
  2. (setq time1 (get-utime))
  3. (T2 700000 LL)
  4. (setq time2 (get-utime))
  5. (princ "\nVL-member方法:")
  6. (princ (- time2 time1))
  7. (princ "s")
  8. )
  9. (defun C:2 ()
  10. (setq time1 (get-utime))
  11. (T3 700000 LL)
  12. (setq time2 (get-utime))
  13. (princ "\n另类mapcar方法:")
  14. (princ (- time2 time1))
  15. (princ "s")
  16. )
  17. (defun C:3 ()
  18. (setq time1 (get-utime))
  19. (XD::List:N+ LL 700000)
  20. (setq time2 (get-utime))
  21. (princ "\n分支方法:")
  22. (princ (- time2 time1))
  23. (princ "s")
  24. )
  25. (defun c:t1 ()
  26.   (setq i 0)
  27.   (setq ll nil)
  28.   (repeat 900000
  29.     (setq ll (cons (setq i (1+ i))
  30.                    ll
  31.              )
  32.     )
  33.   )
  34. )
  35. (defun get-utime () (* 86400.0 (getvar "tdusrtimer")))

  36. ;;=============={ 返回表第N个元素之后的所有元素 }===================
  37. ;;测试: (T2 3  '(2334 556 33 44 66 77 22))==> (44 66 77 22)
  38. (DEFUN T2 (n LST / A)
  39. (setq A 0)
  40. (vl-member-if '(lambda(x)(setq A (1+ A)) (< n A) ) lst)
  41. )
  42. ;;测试: (T3 3  '(2334 556 33 44 66 77 22))==> (44 66 77 22)
  43. (DEFUN T3 (n LST / A)
  44. (setq A 0)
  45. (vl-catch-all-apply 'mapcar (LIST'(lambda(x)(SETQ A (1+ A))(if (< N A) (quit) (setq lst (cdr lst)) ))lst))
  46. lst
  47. )

  48. ;|

  49.    返回表第N个元素之后的所有元素(不包括N)

  50.    参数:
  51.        LST ---- 表
  52.        N   ---- 序号(从1开始)
  53. |;
  54. (defun XD::List:N+ (lst n / lst1 i l)
  55.   (setq l (length lst))
  56.   (cond
  57.     ((< n 1)
  58.       lst
  59.     )
  60.     ((= n 1)
  61.       (cdr lst)
  62.     )
  63.     ((= n 2)
  64.       (cddr lst)
  65.     )
  66.     ((= n 3)
  67.       (cdddr lst)
  68.     )
  69.     ((= n 4)
  70.       (cddddr lst)
  71.     )
  72.     ((and
  73.        (>= n 5)
  74.        (<= l)
  75.      )
  76.       (if (< n 1)
  77.         (setq n 1)
  78.       )
  79.       (setq i 0)
  80.       (if (< n (/ l 2.0))
  81.         (progn
  82.           (while (and
  83.                    (setq a (car lst))
  84.                    (< i n)
  85.                  )
  86.             (setq lst (cdr lst)
  87.                   i (1+ i)
  88.             )
  89.           )
  90.           lst
  91.         )
  92.         (progn
  93.           (setq lst (reverse lst))
  94.           (while (and
  95.                    (setq a (car lst))
  96.                    (< i (- l n))
  97.                  )
  98.             (setq lst1 (cons a lst1)
  99.                   lst (cdr lst)
  100.                   i (1+ i)
  101.             )
  102.           )
  103.           lst1
  104.         )
  105.       )
  106.     )
  107.   )
  108. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-13 15:38:14 | 显示全部楼层
本帖最后由 wowan1314 于 2013-6-13 15:49 编辑

测试结果! 90W数据的表,差别都只在毫秒级。楼主函数两头快中间慢,不过只有一头快过vl-member-if函数.

当N<70W,楼主的函数,搞不赢那两个函数。
当N>70W,楼主的函数才显示出其优势。
当N>80W,函数的差别才达到一百毫秒以上。

测试同时发现,VL-member-if 函数性价比极高。比另类的mapcar的表现还好些.
如果是10W的表。差别仅在几十毫秒之间。实际工程中不晓得数据会在什么级别上。

点评

两头快是肯定的,中间所谓的“慢”也是相对自己,和你们的中间比,是一个数量级的,因为都是都表头到中间。差别也就在FOREACH,WHILE之间的效率差别。这个就是算法体现作用的时候,在机器硬件,函数基本固定情况下,  详情 回复 发表于 2013-6-13 17:51
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-13 17:22:45 | 显示全部楼层
跟据实际测试,调整代码!

此函数为最优函数
  1. ;;=============={ 返回表第N个元素之后的所有元素 }===================
  2. ;;测试: (T6 3  '(2334 556 33 44 66 77 22))==> (44 66 77 22)
  3. (DEFUN T6 (n LST / A NLST L)
  4. (setq A 0 L (LENGTH LST))
  5. (IF (< N (* L 0.65))
  6. (SETQ NLST (vl-member-if '(lambda(x)(setq A (1+ A)) (< n A) ) lst))
  7. (vl-member-if '(lambda(x)(SETQ L (1- L) Nlst (CONS X NLST)) (<= L N) ) (reverse lst))
  8. )
  9. NLST
  10. )

点评

VL-MEMBER-IF 对重复量很大的表,表现如何,葛老测试测试。  详情 回复 发表于 2013-6-13 17:53
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

 楼主| 发表于 2013-6-13 17:51:59 | 显示全部楼层
wowan1314 发表于 2013-6-13 15:38
测试结果! 90W数据的表,差别都只在毫秒级。楼主函数两头快中间慢,不过只有一头快过vl-member-if函数.

...

两头快是肯定的,中间所谓的“慢”也是相对自己,和你们的中间比,是一个数量级的,因为都是都表头到中间。差别也就在FOREACH,WHILE之间的效率差别。这个就是算法体现作用的时候,在机器硬件,函数基本固定情况下,考虑优化的算法是有作用的。当然对今天的硬件来说,只是毫秒级的差距。

看过一个帖子的讨论,对于中间插入,删除这样的操作,VL-REMOVE-IF 这样的函数效率是低的,因为他要遍历所有表,还附带删除操作。

所以,对于必须要遍历所有节点的应用,可以用VL-REMOVE-IF这样的。 对于中间操作然后就结束的,尽量别用。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

 楼主| 发表于 2013-6-13 17:53:22 | 显示全部楼层
wowan1314 发表于 2013-6-13 17:22
跟据实际测试,调整代码!

此函数为最优函数

VL-MEMBER-IF 对重复量很大的表,表现如何,葛老测试测试。

点评

函数及测试函数都给你了。你都懒的运行下看看哦? 100W相同元素表。N=90W。测试结果如下 命令: 1 VL-member方法:0.375s"s" 命令: 3 分支方法:0.125s"s" 命令: 6 分支方法:0.094s"s"  详情 回复 发表于 2013-6-13 19:51
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-13 19:51:32 | 显示全部楼层
本帖最后由 wowan1314 于 2013-6-13 19:59 编辑
Lispboy 发表于 2013-6-13 17:53
VL-MEMBER-IF 对重复量很大的表,表现如何,葛老测试测试。

函数及测试函数都给你了。你都懒的运行下看看哦?

100W相同元素表。N=90W。
命令: 1
VL-member方法:0.375s"s"
命令: 3
分支方法:0.125s"s"
命令: 6
分支方法:0.094s"s"
N=50W
命令: 1
VL-member方法:0.203s"s"
命令:
命令: 3
分支方法:0.469s"s"
命令:
命令: 6
分支方法:0.219s"s"
N=10W
速度一样



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

使用道具 举报

发表于 2013-6-13 19:58:09 | 显示全部楼层
ll_j 发表于 2013-6-13 10:50
其实不要太过纠结于repeat、append、mapcar、cons等函数的效率。
就如本例,repeat可能是最直观的,在n ...

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 01:49 , Processed in 0.207533 second(s), 56 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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