找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1571|回复: 36

[有奖答题] 让VL-POSITION返回多个索引

[复制链接]

已领礼包: 40个

财富等级: 招财进宝

发表于 2017-5-15 09:38:07 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 newer 于 2017-5-16 20:46 编辑

我们知道,vl-position函数只能返回第一个找到元素的索引

比如:

命令: (vl-position 1 '(1 3 2 4 1 4 1))
0


我们自己写个函数 vl-positions , 能返回多个索引,比如上面的:

命令: (vl-positions 1 '(1 3 2 4 1 4 1))
(0 4 6)


抛砖引玉,我来一个:

  1. (defun vl-positions1 ( x l / i )
  2.     (setq i -1)
  3.     (vl-remove nil (mapcar '(lambda ( y ) (setq i (1+ i)) (if (= x y) i)) l))
  4. )


_$ (vl-positions1 1 '(1 3 2 4 1 4 1))
(0 4 6)
_$

附测试效率代码(xd::benchmark函数,需加载晓东通用LISP函数库2017.0518+版本):

  1. (defun vl-positions1 (x l / i)
  2.   (setq i -1)
  3.   (vl-remove nil
  4.              (mapcar '(lambda (y)
  5.                         (setq i (1+ i))
  6.                         (if (= x y)
  7.                           i
  8.                         )
  9.                       )
  10.                      l
  11.              )
  12.   )
  13. )
  14. (defun vl-positions2 (x l / I NEW Y)
  15.   (setq i -1)
  16.   (mapcar '(lambda (y)
  17.              (setq i (1+ i))
  18.              (if (= x y)
  19.                (setq New (cons i New))
  20.              )
  21.            )
  22.           l
  23.   )
  24.   (if New
  25.     (reverse New)
  26.   )
  27. )
  28. (defun vl-positions3 (x l / p)
  29.   (if (setq p (vl-positions3 x l))
  30.     (cons p
  31.           (mapcar
  32.             '(lambda (y)
  33.                (+ 1 p y)
  34.              )
  35.             (vl-positions3 x (cdr (member x l)))
  36.           )
  37.     )
  38.   )
  39. )
  40. (defun vl-positions4 (m l / a ll)
  41.   (setq a -1)
  42.   (foreach n l
  43.     (and
  44.       (setq a (1+ a))
  45.       (= m n)
  46.       (setq ll (cons a ll))
  47.     )
  48.   )
  49.   (reverse ll)
  50. )
  51. (defun vl-positions5 (itm lst / idn nlst)
  52.   (setq idx -1)
  53.   (while (< (setq idx (1+ idx))
  54.             (length lst)
  55.          )
  56.     (and
  57.       (= itm (nth idx lst))
  58.       (setq nlst (cons idx nlst))
  59.     )
  60.   )
  61.   (reverse nlst)
  62. )
  63. (defun vl-positions6 (m l / a b ll)
  64.   (while
  65.     (setq a (vl-position m l))
  66.      (setq l  (cdr (member m l))
  67.            ll (cons (if        (setq b (car ll))
  68.                       (+ 1 a b)
  69.                       a
  70.                     )
  71.                     ll
  72.               )
  73.      )
  74.   )
  75.   (reverse ll)
  76. )
  77. (defun vl-positions7 (m l / a b ll)
  78.   (setq        a  (vl-position m l)
  79.         ll (cons a ll)
  80.         l  (cdr (member m l))
  81.   )
  82.   (while
  83.     (setq a (vl-position m l))
  84.      (setq l  (cdr (member m l))
  85.            ll (cons (+ 1 a (car ll)) ll)
  86.      )
  87.   )
  88.   (reverse ll)
  89. )
  90. (defun vl-positions8 (n l / i j r)
  91.   (setq j -1)
  92.   (while
  93.     (setq i (vl-position n l))
  94.      (setq r (cons (setq j (+ 1 i j)) r))
  95.      (setq l (cdr (member n l)))
  96.   )
  97.   (reverse r)
  98. )
  99. (defun vl-position8 (n l / i ll)
  100.   (setq i 0)
  101.   (foreach x l
  102.     (if        (eq x n)
  103.       (setq ll (cons i ll))
  104.     )
  105.     (setq i (1+ i))
  106.   )
  107.   (reverse ll)
  108. )
  109. (defun vl-positions9 (n l / i j r)
  110.   (setq j -1)
  111.   (while
  112.     (setq i (vl-position n l))
  113.      (setq r (cons (setq j (+ 1 i j)) r))
  114.      (setq l (cdr (member n l)))
  115.   )
  116.   (reverse r)
  117. )
  118. (defun vl-positions10 (l lst / n la ns)
  119.   (setq        n  0
  120.         la (car lst)
  121.   )
  122.   (if (= la l)
  123.     (setq ns (cons n ns))
  124.   )
  125.   (while (setq lst (cdr lst))
  126.     (setq la (car lst)
  127.           n  (1+ n)
  128.     )
  129.     (if        (= la l)
  130.       (setq ns (cons n ns))
  131.     )
  132.   )
  133.   (reverse ns)
  134. )
  135. (defun vl-positions11 (a lst)
  136.   (setq i -1)
  137.   (setq        flst
  138.          (vl-remove 0
  139.                     (mapcar '*
  140.                             (mapcar '(lambda (x)
  141.                                        (if (= a x)
  142.                                          1
  143.                                          0
  144.                                        )
  145.                                      )
  146.                                     lst
  147.                             )
  148.                             (mapcar '(lambda (y) (setq i (+ i 1))) lst)
  149.                     )
  150.          )
  151.   )
  152.   (if (= a (car lst))
  153.     (setq flst (cons 0 flst))
  154.   )
  155.   flst
  156. )
  157. (defun c:test ()
  158.   (setq lst '(1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4))
  159.   (xd::benchmark
  160.     '((vl-positions1 1 lst)
  161.       (vl-positions2 1 lst)
  162.       (vl-positions4 1 lst)
  163.       (vl-positions5 1 lst)
  164.       (vl-positions6 1 lst)
  165.       (vl-positions7 1 lst)
  166.       (vl-positions8 1 lst)
  167.       (vl-positions9 1 lst)
  168.       (vl-positions10 1 lst)
  169.       (vl-positions11 1 lst)
  170.      )
  171.   )
  172.   (princ)
  173. )





加入vl-positions11测试结果


  1. 命令: (repeat 5 (c:test))
  2. Elapsed milliseconds / relative speed for 32768 iteration(s):

  3.     (VL-POSITIONS7 1 LST)......1437 / 2.76 <fastest>
  4.     (VL-POSITIONS9 1 LST)......1609 / 2.47
  5.     (VL-POSITIONS6 1 LST)......1625 / 2.44
  6.     (VL-POSITIONS10 1 LST).....1671 / 2.38
  7.     (VL-POSITIONS8 1 LST)......1859 / 2.14
  8.     (VL-POSITIONS1 1 LST)......1938 / 2.05
  9.     (VL-POSITIONS2 1 LST)......1968 / 2.02
  10.     (VL-POSITIONS4 1 LST)......1984 / 2
  11.     (VL-POSITIONS5 1 LST)......2156 / 1.84
  12.     (VL-POSITIONS11 1 LST).....3969 / 1 <slowest>
  13. Elapsed milliseconds / relative speed for 32768 iteration(s):

  14.     (VL-POSITIONS6 1 LST).......1985 / 8.45 <fastest>
  15.     (VL-POSITIONS8 1 LST).......2172 / 7.72
  16.     (VL-POSITIONS7 1 LST).......2250 / 7.45
  17.     (VL-POSITIONS4 1 LST).......2406 / 6.97
  18.     (VL-POSITIONS2 1 LST).......2860 / 5.86
  19.     (VL-POSITIONS5 1 LST).......2938 / 5.71
  20.     (VL-POSITIONS1 1 LST).......3047 / 5.5
  21.     (VL-POSITIONS9 1 LST).......3703 / 4.53
  22.     (VL-POSITIONS10 1 LST)......6687 / 2.51
  23.     (VL-POSITIONS11 1 LST).....16765 / 1 <slowest>
  24. Elapsed milliseconds / relative speed for 32768 iteration(s):

  25.     (VL-POSITIONS6 1 LST)......1735 / 2.22 <fastest>
  26.     (VL-POSITIONS8 1 LST)......1906 / 2.02
  27.     (VL-POSITIONS9 1 LST)......2000 / 1.92
  28.     (VL-POSITIONS7 1 LST)......2016 / 1.91
  29.     (VL-POSITIONS10 1 LST).....2203 / 1.74
  30.     (VL-POSITIONS4 1 LST)......2297 / 1.67
  31.     (VL-POSITIONS5 1 LST)......2407 / 1.6
  32.     (VL-POSITIONS2 1 LST)......2672 / 1.44
  33.     (VL-POSITIONS1 1 LST)......2766 / 1.39
  34.     (VL-POSITIONS11 1 LST).....3844 / 1 <slowest>
  35. Elapsed milliseconds / relative speed for 32768 iteration(s):

  36.     (VL-POSITIONS7 1 LST)......1375 / 2.64 <fastest>
  37.     (VL-POSITIONS8 1 LST)......1406 / 2.58
  38.     (VL-POSITIONS9 1 LST)......1531 / 2.37
  39.     (VL-POSITIONS6 1 LST)......1594 / 2.27
  40.     (VL-POSITIONS4 1 LST)......2000 / 1.81
  41.     (VL-POSITIONS10 1 LST).....2016 / 1.8
  42.     (VL-POSITIONS5 1 LST)......2500 / 1.45
  43.     (VL-POSITIONS2 1 LST)......2531 / 1.43
  44.     (VL-POSITIONS1 1 LST)......2859 / 1.27
  45.     (VL-POSITIONS11 1 LST).....3625 / 1 <slowest>
  46. Elapsed milliseconds / relative speed for 32768 iteration(s):

  47.     (VL-POSITIONS7 1 LST)......1343 / 2.62 <fastest>
  48.     (VL-POSITIONS8 1 LST)......1469 / 2.39
  49.     (VL-POSITIONS6 1 LST)......1547 / 2.27
  50.     (VL-POSITIONS9 1 LST)......1687 / 2.08
  51.     (VL-POSITIONS4 1 LST)......1984 / 1.77
  52.     (VL-POSITIONS1 1 LST)......2047 / 1.72
  53.     (VL-POSITIONS10 1 LST).....2219 / 1.58
  54.     (VL-POSITIONS2 1 LST)......2250 / 1.56
  55.     (VL-POSITIONS5 1 LST)......2281 / 1.54
  56.     (VL-POSITIONS11 1 LST).....3516 / 1 <slowest>

复制代码



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

已领礼包: 604个

财富等级: 财运亨通

发表于 2017-5-15 10:31:26 | 显示全部楼层
本帖最后由 newer 于 2017-5-15 17:25 编辑

  1. (defun vl-positions2 (x l / I NEW Y)
  2.   (setq i -1)
  3.   (mapcar '(lambda (y)
  4.              (setq i (1+ i))
  5.              (if (= x y)
  6.                (setq New (cons i New))
  7.              )
  8.            )
  9.           l
  10.   )
  11. (if New (reverse New))
  12. )

评分

参与人数 1威望 +1 D豆 +5 贡献 +1 收起 理由
newer + 1 + 5 + 1 热心帮忙奖!

查看全部评分

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

使用道具 举报

已领礼包: 20个

财富等级: 恭喜发财

发表于 2017-5-15 14:49:48 | 显示全部楼层
本帖最后由 newer 于 2017-5-16 20:09 编辑

来一个递归的
  1. (defun vl-positions3 (x l / p)
  2.   (if (setq p (vl-position x l))
  3.     (cons p
  4.           (mapcar
  5.             '(lambda (y)
  6.                (+ 1 p y)
  7.              )
  8.             (vl-positions3 x (cdr (member x l)))
  9.           )
  10.     )
  11.   )
  12. )

评分

参与人数 1威望 +1 D豆 +5 贡献 +1 收起 理由
newer + 1 + 5 + 1 热心帮忙奖!

查看全部评分

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

使用道具 举报

发表于 2017-5-15 17:14:52 | 显示全部楼层
本帖最后由 newer 于 2017-5-15 19:08 编辑

  1. (defun vl-positions4 (m l / a ll)  (setq a -1)
  2.   (foreach n l
  3.     (and
  4.       (setq a (1+ a))
  5.       (= m n)
  6.       (setq ll (cons a ll))
  7.     )
  8.   )
  9.   (reverse ll)
  10. )




评分

参与人数 1威望 +1 D豆 +5 贡献 +1 收起 理由
newer + 1 + 5 + 1 热心帮忙奖!

查看全部评分

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

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2017-5-15 17:23:05 | 显示全部楼层
本帖最后由 newer 于 2017-5-15 19:08 编辑

  1. (defun vl-positions5 (itm lst / idn nlst)
  2.   (setq idx -1)
  3.   (while (< (setq idx (1+ idx))
  4.             (length lst)
  5.          )
  6.     (and
  7.       (= itm (nth idx lst))
  8.       (setq nlst (cons idx nlst))
  9.     )
  10.   )
  11.   (reverse nlst)
  12. )




评分

参与人数 1威望 +1 D豆 +5 贡献 +1 收起 理由
newer + 1 + 5 + 1 热心帮忙奖!

查看全部评分

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

使用道具 举报

发表于 2017-5-15 18:17:46 | 显示全部楼层
本帖最后由 newer 于 2017-5-15 19:08 编辑

  1. (defun vl-positions6 (m l / a b ll)
  2.     (while
  3.         (setq a (vl-position m l))
  4.         (setq l (cdr (member m l))ll (cons (if (setq b (car ll)) (+ 1 a b) a) ll))
  5.     )
  6.     (reverse ll)
  7. )


还是二楼递归的叼!

评分

参与人数 1威望 +1 D豆 +5 贡献 +1 收起 理由
newer + 1 + 5 + 1

查看全部评分

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2017-5-15 18:35:47 | 显示全部楼层

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

使用道具 举报

发表于 2017-5-15 18:54:23 | 显示全部楼层

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2017-5-15 19:07:29 | 显示全部楼层
本帖最后由 newer 于 2017-5-15 19:10 编辑

公布下测试结果

Elapsed milliseconds / relative speed for 16384 iteration(s):

    (VL-POSITIONS6 1 LST).....1328 / 1.34 <fastest>
    (VL-POSITIONS4 1 LST).....1359 / 1.31
    (VL-POSITIONS5 1 LST).....1625 / 1.1
    (VL-POSITIONS1 1 LST).....1719 / 1.04
    (VL-POSITIONS2 1 LST).....1781 / 1 <slowest>


不幸的是,递归那个测试时候堆栈溢出,所以尽可能还是别用递归,大数据不行。

目前,暂时,最快的是VL-POSITIONS6,最慢的是VL-POSITIONS2

看看,谁还能写出更快的不? 测试工具在一楼, c:test



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

使用道具 举报

发表于 2017-5-15 19:13:14 | 显示全部楼层

哈哈! 我写的两个最快!

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2017-5-15 19:15:52 | 显示全部楼层

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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2017-5-15 19:17:02 | 显示全部楼层

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

使用道具 举报

发表于 2017-5-15 19:21:22 | 显示全部楼层
本帖最后由 newer 于 2017-5-15 19:28 编辑

  1. (defun vl-positions7 (m l / a b ll)
  2.     (setq ll (cons (vl-position m l) ll) l (cdr (member m l)))
  3.     (while
  4.         (setq a (vl-position m l))
  5.         (setq l (cdr (member m l))ll(cons(+ 1 a (car ll))ll))
  6.     )
  7.     (reverse ll)
  8. )




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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

 楼主| 发表于 2017-5-15 19:26:52 | 显示全部楼层

还是6快

Elapsed milliseconds / relative speed for 16384 iteration(s):

    (VL-POSITIONS6 1 LST).....1203 / 1.66 <fastest>
    (VL-POSITIONS7 1 LST).....1281 / 1.56
    (VL-POSITIONS4 1 LST).....1344 / 1.49
    (VL-POSITIONS5 1 LST).....1750 / 1.14
    (VL-POSITIONS1 1 LST).....1953 / 1.02
    (VL-POSITIONS2 1 LST).....2000 / 1 <slowest>


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

使用道具 举报

发表于 2017-5-15 19:28:45 | 显示全部楼层

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-19 17:52 , Processed in 0.452534 second(s), 64 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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