找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1414|回复: 8

[求助] 求将一维表转为3个一组的二维表的函数

[复制链接]

已领礼包: 1个

财富等级: 恭喜发财

发表于 2013-5-27 23:28:59 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 yxpxa 于 2013-5-27 23:31 编辑

;; 这个函数运行效率是不是慢了些,如何能用 mapcar 改善?
(defun split3 (Lt / Lts)
  (while (or (car Lt) (cadr Lt)(caddr Lt))
    (setq Lts (cons (list (car Lt) (cadr Lt) (caddr Lt)) Lts)
          Lt (cdr(cdr(cdr Lt)))
    ))  (reverse Lts)
)

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

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-28 00:25:49 | 显示全部楼层
这样吧,应该比你那个能快点。
  1.    (while (cdddr aa)
  2.       (setq bb (cons (list (car aa)(cadr aa)(caddr aa)) bb))
  3.       (setq aa (cdddr aa))
  4.    )
  5.    (append (reverse bb) (list aa))
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 6530个

财富等级: 富甲天下

发表于 2013-5-28 13:26:41 | 显示全部楼层
试试这样:
  1. (defun tt (x)
  2.   (if (cdddr x)
  3.     (cons (list (car x) (cadr x) (caddr x)) (tt (cdddr x)))
  4.     (cons x nil)
  5.   )
  6. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-28 14:32:49 | 显示全部楼层

那天的讨论帖里面得到一个结论,就是在处理表结构时候,尽量少用递归。迭代可以简单就能做到的,就不要递归。

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

使用道具 举报

已领礼包: 6530个

财富等级: 富甲天下

发表于 2013-5-28 15:31:20 | 显示全部楼层
Lispboy 发表于 2013-5-28 14:32
那天的讨论帖里面得到一个结论,就是在处理表结构时候,尽量少用递归。迭代可以简单就能做到的,就不要递 ...

这种观点我很早就提出来过,实际上是不正确的。
实际上,car、cdr这种表述形式本身就是一种递归,只是没有从形式上表现出来而已,对于表结构,每一层“嵌套”(函数调用),或多或少地都有一些东西压入堆栈,如果程序的逻辑和语法没有错误,这种压入是有限的,很难出现“溢出”的现象,但如果语法混乱,则递归会比其它算法结构更容易出现错误。
前两天的测试,凡有递归的都溢出,并不代表递归不好,而主要是测试的“量”太过,当然,程序本身也可能并不完善,明知这种语法可能产生堆栈溢出还一定要用,那么就不是语法本身的问题了。
我们测试语法,更多地是为了实用,这就是明知递归有这个问题,还仍旧在一些程序中能见到的原因,要知道,把一个语法良好的递归使用到溢出还是要费一点功夫的,就拿我的这个函数而言,我测试了一千多个原子的表,仍旧没有溢出,还不行么?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 51个

财富等级: 招财进宝

发表于 2013-5-28 16:34:06 | 显示全部楼层
本帖最后由 Lispboy 于 2013-5-28 16:38 编辑
ll_j 发表于 2013-5-28 15:31
这种观点我很早就提出来过,实际上是不正确的。
实际上,car、cdr这种表述形式本身就是一种递归,只是没 ...

长老,你看

  1.    (while (cdddr aa)
  2.       (setq bb (cons (list (car aa)(cadr aa)(caddr aa)) bb))
  3.       (setq aa (cdddr aa))
  4.    )
  5.    (append (reverse bb) (list aa))


和你的代码
  1. (defun tt (x)
  2.   (if (cdddr x)
  3.     (cons (list (car x) (cadr x) (caddr x)) (tt (cdddr x)))
  4.     (cons x nil)
  5.   )
  6. )


代码行数是一样的,但是你用了递归,上面的帖子我说的是迭代能简单就能实现的,就是这种,为什么要硬改成递归呢? 楼主在谈效率,递归的优点是能简化代码,你这个代码没做到,但递归的副作用是效率差,因为要多了很多的函数调用,入栈,出栈。

提高代码效率的一个途径就是尽量减少函数的调用,何况堆栈了。所以很多编译的软件都有嵌入代码编译,直接把定义的函数变成迭代的代码嵌入到程序中。

函数调用就涉及到入栈出栈,一次正常的调用函数还好,递归要很多很多的这样操作啊(不谈空间的使用问题),表数量少还行,几千,上万的,额外要比迭代的,多了上万的*3 (至少)额外代码执行时间。要是多重循环的,那就死在那了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

 楼主| 发表于 2013-5-28 17:06:48 | 显示全部楼层
本帖最后由 yxpxa 于 2013-5-28 17:34 编辑

感谢,学习中
我们都是应用级别的,效率这个问题太深可能会涉及lisp表的结构原理。
不过有些函数比如 append 确实不敢多用,这个函数对速度的影响太致命了。

下面是base64码转换程序,改写了好多版,一直在实验各函数的运行效率,
努力提高转换速度,现在转换一个50kB以内的文件大约不到0.3秒就完成。
测试了一个 3MB的文件,需要运行3分钟时间。3MB文件以二进制读入表后,
表的长度为 3000*1000*8= 两千四百万个元素,没有崩溃!说明表结构还是相当的稳定。
其结果表明,运算速度和表长度(文件大小)的平方成正比。
主要是每次运算进制转换都要对整个表(相当于整个文件)进行操作,
我还不会按数据流处理,也就是指针的概念吧。
请点击此处下载

查看状态:需购买或无权限

您的用户组是:游客

文件名称:chb.rar 
下载次数:3  文件大小:5.01 KB 
下载权限: 不限 以上  [免费赚D豆]


所以lisp也就是在CAD里玩玩,由lisp进化而成的python语言就强大的多。




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

使用道具 举报

已领礼包: 40个

财富等级: 招财进宝

发表于 2013-5-28 17:30:34 | 显示全部楼层
yxpxa 发表于 2013-5-28 17:06
感谢,学习中
我们都是应用级别的,效率这个问题太深可能会涉及lisp表的结构原理。
不过有些函数比如 app ...

http://bbs.xdcad.net/forum.php?m ... 425&pid=3459026

看看这个帖子,不知道能否有帮助,附件VLX看不到代码,也不清楚你的表结构。多层循环的尽可能变成一层循环,用MAPCAR处理表数据,都应该可以做到的。

点评

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-25 14:21 , Processed in 0.543599 second(s), 50 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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