明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 772|回复: 13

[讨论] 求多维数组转5维数组的非递归方法

[复制链接]
发表于 2022-10-3 14:22 | 显示全部楼层 |阅读模式
本帖最后由 guosheyang 于 2022-10-4 18:51 编辑

朋友们  这个是根据caoyin版主的代码改的,列表按5个分组,用的是递归法,如果不用递归法的话,能否达到这个代码运行的速度,代码需要怎样组织? 谢谢!
;多维数组转5维数组               
;(MD->5D (setq l'(1 4 7 10 13 16 19 24 33 46 3 6 9 12 15 18 21 67 43 78 2 5 8 11 14 17 20 76 78 99)))

(defun md->5d (L)
  (if (>(length L)5)
    (cons (list (car L)(cadr L)(caddr L)(cadddr L)(cadddr(cdr L)))
            (md->5d (cddddr(cdr L)))
    )
    (list L)
  )
)


;测试
(progn
(setq stime (getvar "millisecs"));;计时起点
  (repeat 100000
   (md->5d L)
  )
(setq zsj(-(getvar "millisecs") stime))
)






"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2022-10-4 22:14 | 显示全部楼层
本帖最后由 tigcat 于 2022-10-4 22:43 编辑
guosheyang 发表于 2022-10-4 19:03
tigcat朋友说的没错  当数据量大的时候(复制成6万个左右的数字) ,的确while循环的代码(caoyin版主的 ...

guosheyang大侠研究仔细,学习啦.晚上有点时间,我也试了试caoyin版主的代码,证实效率很高
(setq l'(1 4 7 10 13 16 19 24 33 46 3 6 9 12 15 18 21 67 43 78 2 5 8 11 14 17 20 76 78 99))
(repeat 12 (setq L(append L L)));有122880数据
(defun tt (lst /)
  (setq stime (getvar "millisecs"))
  (while lst
    (setq lst2 (cons (list (car lst) (cadr lst) (caddr lst) (cadddr lst) (cadddr (cdr lst))) lst2)
          lst  (cddddr (cdr lst))
    )
  )
  (reverse lst2)
  (setq zsj(-(getvar "millisecs") stime))
)
;(tt l)
;运行了好几次都在100ms以下,最快30ms,最慢91ms,平均值60ms左右。基本我的老爷机都是秒出结果


;;;;2#我写的也测试了一把

(defun tt(lst / )
  (setq stime (getvar "millisecs"))
(setq i 0 lst1 nil lst2 nil)
(repeat (/ (length l) 5)
  (repeat 5
    (setq lst1(cons (nth i l) lst1))
    (setq i (1+ i))
    )
  (setq lst2 (cons (reverse lst1) lst2))
  (setq lst1 nil)
  
  )
(reverse lst2)
  (setq zsj(-(getvar "millisecs") stime))
)

;最后用时25188ms,好慢啊


;;;caoyin版主建议第一个reverse取消,用list组表,根据版主建议,改写2楼的代码

(defun tt(lst / )
  (setq stime (getvar "millisecs"))
(setq i 0 lst1 nil lst2 nil)
(repeat (/ (length l) 5)
  
    (setq lst1(list (car lst)(cadr lst)(caddr lst)(cadddr lst)(cadddr (cdr lst))))
   
   
  (setq lst2 (cons  lst1 lst2))
  (setq lst1 nil)
  (setq lst (cdr (cddddr lst)))
  )
(reverse lst2)
  (setq zsj(-(getvar "millisecs") stime))
)
;这个运行速度和版主的差不多啦.从25000ms提升到50ms左右,提升了499倍,当然我这代码简洁度差caoyin版主的可就多啦




;;;;楼主前些天发帖的代码我也试了试

(defun @group (lst n / item )
   (setq stime (getvar "millisecs"))
    (foreach element(reverse lst)
      (setq item(cons element item))
      (if(= (length item) n)
         (setq new (cons item new) item nil)
      )
    )
    (setq zsj(-(getvar "millisecs") stime))
);结果在100ms-120ms之间,保持了极高的速率,并且是通用的。



;以上测试均默认维数n与表L的长度是整数倍关系。

发表于 2022-10-4 07:51 | 显示全部楼层
本帖最后由 caoyin 于 2022-10-4 08:03 编辑
tigcat 发表于 2022-10-3 22:46
我觉得单纯的repeat10万次,不知道会不会失真。最好是找一组有10万个数据的表处理看看速度。另外有些程序 ...

递归的优点缺点都很明显:
优点:避免reverse,每一次reverse都是一次遍历。
  2楼的代码把第一个 reverse 换掉,
  改成car、cadr、caddr、cadddr、cadddr+cdr估计速度会提升一倍
缺点:递归有堆栈次数的限制,处理一般手动生成的数据没啥问题。如你5楼所说处理10万数据的表就行不通。


--------------------------------------------------------------
2楼代码改为下面的结构:

(defun tt (lst / lst2)
  (while lst
    (setq lst2 (cons (list (car lst) (cadr lst) (caddr lst) (cadddr lst) (cadddr (cdr lst))) lst2)
          lst  (cddddr (cdr lst))
    )
  )
  (reverse lst2)
)

评分

参与人数 2明经币 +2 金钱 +5 收起 理由
guosheyang + 1 很给力!
tigcat + 1 + 5 很给力!

查看全部评分

 楼主| 发表于 2022-10-4 19:03 | 显示全部楼层
本帖最后由 guosheyang 于 2022-10-4 19:28 编辑
tigcat 发表于 2022-10-3 22:46
我觉得单纯的repeat10万次,不知道会不会失真。最好是找一组有10万个数据的表处理看看速度。另外有些程序 ...

tigcat朋友说的没错  当数据量大的时候(复制成6万个左右的数字) ,的确while循环的代码(caoyin版主的那个)运行快得多   差不多80:1000  
当我把数据复制成11万多时   递归的代码停摆了
发表于 2022-10-3 15:19 | 显示全部楼层
本帖最后由 tigcat 于 2022-10-3 15:41 编辑

感觉跟前面的一样的啊,试了试caoyin版主的递归用时是这个的1/4,这个写得不好
(defun tt()
(setq i 0 lst1 nil lst2 nil)
(repeat (/ (length l) 5)
  (repeat 5
    (setq lst1(cons (nth i l) lst1))
    (setq i (1+ i))
    )
  (setq lst2 (cons (reverse lst1) lst2))
  (setq lst1 nil)
  
  )
(reverse lst2)
)
 楼主| 发表于 2022-10-3 15:43 | 显示全部楼层
本帖最后由 guosheyang 于 2022-10-3 15:46 编辑
tigcat 发表于 2022-10-3 15:19
感觉跟前面的一样的啊,试了试caoyin版主的递归用时是这个的1/4,这个写得不好
(defun tt()
(setq i 0 lst1 ...

嗯   就是看能否达到递归的那个速度?以前很多人不是说递归慢吗  好像还不完全是那样哈
发表于 2022-10-3 22:00 | 显示全部楼层
guosheyang 发表于 2022-10-3 15:43
嗯   就是看能否达到递归的那个速度?以前很多人不是说递归慢吗  好像还不完全是那样哈

你对递归还不是很了解。
发表于 2022-10-3 22:46 | 显示全部楼层
mahuan1279 发表于 2022-10-3 22:00
你对递归还不是很了解。

我觉得单纯的repeat10万次,不知道会不会失真。最好是找一组有10万个数据的表处理看看速度。另外有些程序编译fas后跑得比编译前的lsp快。
楼主学习能力很强,看了caoyin版主的代码马上可以自己改写一个,佩服。
发表于 2022-10-4 08:59 | 显示全部楼层
caoyin 发表于 2022-10-4 07:51
递归的优点缺点都很明显:
优点:避免reverse,每一次reverse都是一次遍历。
  2楼的代码把第一个 reve ...

谢谢caoyin版主的指点,代码很简洁,学习啦!
 楼主| 发表于 2022-10-4 18:53 | 显示全部楼层
mahuan1279 发表于 2022-10-3 22:00
你对递归还不是很了解。

嗯  是的  递归平时用的不多  
 楼主| 发表于 2022-10-4 18:54 | 显示全部楼层
caoyin 发表于 2022-10-4 07:51
递归的优点缺点都很明显:
优点:避免reverse,每一次reverse都是一次遍历。
  2楼的代码把第一个 reve ...

版主的这个代码运行够快了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-20 02:30 , Processed in 0.341632 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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