找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1625|回复: 23

[讨论]:如何将表炸开?

[复制链接]
发表于 2004-1-24 04:12:58 | 显示全部楼层 |阅读模式

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

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

×
for example
'((0 . 1) 2 (3 (4 5 6)))  -> (0 1 2 3 4 5 6)
不限制表嵌套次数
看谁写的精简
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2004-1-24 09:31:49 | 显示全部楼层
试试这个
(defun c:tt(/ a  lst_simple)
  (setq a '((abc)(1  "a") (3 4 5 "111" "ss")))
  (explode_lst a)
  (princ lst_simple)
  )
(defun explode_lst (lst / n )  
  (foreach n lst
    (if (listp n)
      (explode_lst n)
      (setq lst_simple (append lst_str (list n )))      
    )
  )  
)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-1-24 13:17:57 | 显示全部楼层
好像不对?
Command: tt
(ss)("ss")
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-1-24 22:24:20 | 显示全部楼层
贴的时候改错了代码~
试试下面的~
(defun c:tt (/ a lst_simple)
  (setq a '((abc) (1 "a") (3 4 5 "111" "ss")))
  (explode_lst a)
  (princ lst_simple)
)
(defun explode_lst (lst / n)
  (foreach n lst
    (if        (listp n)
      (explode_lst n)
      (setq lst_simple (append lst_simple (list n)))
    )
  )
)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-1-25 12:10:58 | 显示全部楼层
恩,可以了。还有别的写法么?
另外,如果含点对,如何再处理一下呢?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-25 17:58:14 | 显示全部楼层

  1. (defun flat-li(li / new)
  2.   (defun flat-li1(li / a)
  3.    (while(setq a (if(listp li)(car li)li))
  4.      (if(atom a)
  5.        (setq new(cons a new))
  6.        (flat-li1 a)
  7.      )
  8.      (setq li(if(listp li)(cdr li)nil))
  9.   ))
  10. (flat-li1 li)
  11. (reverse new))


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

使用道具 举报

 楼主| 发表于 2004-1-25 21:47:39 | 显示全部楼层
这个写的不错。加分
还有另外的写法么?我看还有,谁来?

还没啊,那我自己来一个。
写这个主要是循环和对表的处理两个技术,vl中表处理的函数有很多。因此可发挥的余地也很多。
我自己写了几个程序,下面这两个因为代码不够精练,已经被淘汰。

  1. (defun xl_exp (lst / a b c)
  2.   (while (setq a nil c (vl-member-if 'listp lst))
  3.          (repeat (- (length lst)(length c)) (setq a (append a (list (car lst))) lst (cdr lst)))  ;不能用member+reverse.
  4.          (setq b (car c)
  5.               lst(append a (if (atom (cdr b)) (list (car b)(cdr b)) b) (cdr c)))
  6.          (xl_exp lst)
  7.   )lst
  8. )

  1. (defun xl_exp (lst) ;ok!
  2.   (mapcar '(lambda (n)
  3.              (if (listp n)
  4.                (xl_exp (if (atom (cdr n)) (list (car n)(cdr n)) n))
  5.                (setq nlst (append nlst (list n))))
  6.              ) lst)
  7.   nlst
  8. )

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

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-27 01:38:52 | 显示全部楼层
最初由 陌生人 发布
[B]这个写的不错。加分
还有另外的写法么?我看还有,谁来?

还没啊,那我自己来一个。
写这个主要是循环和对表的处理两个技术,vl中表处理的函数有很多。因此可发挥的余地也很多。
我自己写了几个程序,下面这两... [/B]


你上面用了length
下面用的mapcar,对点对表都不行的.

命令: (xl_exp '(1 2 3 . 4))

错误: 列表错误: 4




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

使用道具 举报

 楼主| 发表于 2004-1-27 02:59:23 | 显示全部楼层
'(1 2 3 . 4)
这个是点对表么?别误导初学者!你写的这个表我在cad里面还从来没见过。
要有的话,你自己看看:
Command: '(1 2 3 . 4)
错误: 参数类型错误: consp 4
这个是你写的表本身就是错误的,别赖到我的程序上来!
点对表是 (元素 .  元素) ,顾名思义都可以相像出来。
不错,你的程序支持这种“表”,我测试了一下。
Command: (flat-li '(1 2 3 . 4))
(1 2 3 4)
但是支持也没用,cad里面根本就没这种"表"。
拿正确的点对表来测试应该是:
Command: (xl_exp '(1 2 (3 . 4)))
(1 2 3 4)

对点对表的处理跟用mapcar还是length有什么关系?晕!前者不过是程序结构的函数,后者是计数的函数,难道还不能算数了?计算机就是个算数的机器。
(if (and (listp b)(atom (cdr b))) (list (car b)(cdr b)) b)这句才是对点对表进行处理的语句。

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

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2004-1-27 17:57:19 | 显示全部楼层
最初由 陌生人 发布
[B]'(1 2 3 . 4)
这个是点对表么?别误导初学者!你写的这个表我在cad里面还从来没见过。
要有的话,你自己看看:
Command: '(1 2 3 . 4)
错误: 参数类型错误: consp 4
这个是你写的表本身就是错误的,别赖到我的?.. [/B]

看看韩国(朝鲜?)人的帖子

Examples

_$ (vl-list* 1)

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

使用道具 举报

 楼主| 发表于 2004-1-27 19:52:35 | 显示全部楼层
最初由 eachy 发布
[B][QUOTE]最初由 陌生人 发布
[B]'(1 2 3 . 4)
这个是点对表么?别误导初学者!你写的这个表我在cad里面还从来没见过。
要有的话,你自己看看:
Command: '(1 2 3 . 4)
错误: 参数类型错误: consp 4
这个... [/B]

谢谢eachy版主回复,你真是见识多广
我查了下帮助


  1. 1。
  2. AutoCAD 用表来组织数据的另一种方法是使用一种特殊类型的表:点对。[color=red]点对是一种表,它必须包含两个成员。[/color]在表示点对时,AutoLISP 用一个句号 (.) 分隔表的两个元素。大多数表处理函数都不能以点对作为参数,因此应该确保将正确类型的表传递给函数。
  3. 点对是一种“不规则表”,这种表中的最后一个 cdr 不是 nil。cons 函数除了在表的开始处添加项以外,还能创建点对。如果 cons 函数的第二个参数不是另一个表或 nil,则它将创建一个点对。

  4. _$  (setq sublist (cons 'lyr "WALLS"))

  5. (LYR . "WALLS")


  1. 2。
  2. 构造并返回表
  3. (vl-list*  object [object]...)
  4. 参数
  5. object
  6. 任何 LISP 数据。
  7. 返回值
  8. vl-list* 函数与 list 函数类似,但它将最后一个 object 置于结果列表的最后一个 cdr 处。如果 vl-list* 的最后一个参数为原子,[color=red]则结果为点对表。[/color]如果最后一个参数为表,则其中的元素被附加到构造的表中,置于所有原先加入表的参数之后。可能的返回值有:

  9. 如果 object 指定单一原子,则为原子。
  10.         如果所有 object 参数都是原子,则为点对。
  11.         如果最后一个参数为原子,且不属于前面几种情况,则返回点对表。
  12.         如果不属于前面几种情况,则返回表。
  13. 样例
  14. _$ (vl-list* 1)
  15. 1
  16. _$ (vl-list* 0 "text")
  17. (0 . "TEXT")
  18. _$ (vl-list* 1 2 3)
  19. [color=red](1 2 . 3) [/color]
  20. _$ (vl-list* 1 2 '(3 4))
  21. (1 2 3 4)

从上面看,似乎2中vl-list* 对点对的认定和1中对点对的定义不吻合。vlisp环境中返回(1 2 . 3)这样的表是正常的,带着疑问,测试一下,vl环境:
_$ (vl-list* 2 3 4)
(2 3 . 4)
cad命令行下:
Command: (setq a (vl-list* 2 3 4))
(2 3 . 4)
Command: (car a)
2
Command: (cadr a)
3
Command: (caddr a)
错误: 参数类型错误: 4
Command: (last a)
错误: 列表错误: 4
Command: (cdr a)
(3 . 4)
Command: (cddr a)
4
Command: (type (cdr a))
LIST
看来 (2 3 . 4) 等效于(2 (3 .4))
是不是(2 3 . 4)不是点对表,只是(2 (3 . 4))的另外一种写法?原则上说是正常的表.只有(2 3 . 4)里面的 3 . 4才是点对(不是点对表)。由此可见(2 3)与(2 3 . 4)所占用cad字节是一样的,正常的表元素包含一个向下的指针,而点对没有指针,以点对的第二个元素来占用.
因此,点对"3 . 4"是一个元素(原子),点对表"(3 . 4)"才是表。
同时,我的程序没能处理这样的表(虽然几乎没人这么写),确实是不完善。有待改进。

如此,明白了。谢谢ea版主,上贴对aeo版主语气有所不敬,在此道歉。作版主应该大气些,你不会耿耿于怀吧?;)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-1-27 20:08:47 | 显示全部楼层
点对表,要放弃一切普通表的函数:
length mapcar foreach ......

命令: (cons 2(cons 3 4))
(2 3 . 4)
这是很有可能就会写出来的.

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

使用道具 举报

 楼主| 发表于 2004-1-27 20:36:16 | 显示全部楼层
再测试。
_$ (setq a '(2 3 . 4) b '(2 (3 . 4)))
(2 (3 . 4))
_$ (cadr a)
3
_$ (cadr b)
(3 . 4)
_$ (last a)

错误: 列表错误: 4
_$ (last b)
(3 . 4)
_$ (cddr a)
4
_$ (cddr b)
nil
_$ (cdr a)
(3 . 4)
_$ (cdr b)
((3 . 4))
_$ (cddr '(2 3 . 4))
4
_$ (cdadr '(2 (3 . 4)))
4
看来(2 3 . 4)和 (2 (3 . 4))还不一样,这是个有点古怪的表。取出数据容易搞混淆弄错,怪不得以前没在具体程序中见过。
看来中文帮助里面的翻译以后应该区分一下了。 3 . 4是点对,(3 . 4)才是点对表。是不是可这么理解,点对的第一元素是索引位,第二元素是数据位,数据位要用(cdr )取出,
错误: 关联列表错误: (2 3 . 4)
_$ (assoc 3 '(2 3 . 4))

错误: 关联列表错误: (2 3 . 4)
_$ (assoc 3 (cdr (2 3 . 4)))

错误: 函数调用语法错误: (2 3 . 4)
_$ (assoc 3 (cadr (2 3 . 4)))

错误: 函数调用语法错误: (2 3 . 4)
_$
看来用来这样的表,连索引都不行了。只能用cddr取出数据位"4".如果是(1 2 3 . 4)要用cdddr
因此限制很多
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-1-27 20:49:50 | 显示全部楼层
可以把表变成字符串,去掉所有的括号和点对,再还原回一个新表
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-1-27 21:16:11 | 显示全部楼层
最初由 mmmm 发布
[B]可以把表变成字符串,去掉所有的括号和点对,再还原回一个新表 [/B]

好建议,我原先也想过,但是因为元素中字符的情况很多,因此没深入并写程序,看了你的回贴,我也试试写了一个。

  1. (defun xl_exp (lst / str)
  2.   (setq str (vl-prin1-to-string lst))
  3.   (while (wcmatch str "*(*,*)*,* . *")
  4.     (foreach n '("(" ")" " . ")(setq str(vl-string-subst  " " n str)))
  5.   )
  6.   (read (strcat "(" str ")"))
  7. )
  8. ;(xl_exp '((0 . 1) 2 (3 (4 . (5 (6 . 7)))))) -> (0 1 2 3 4 5 6 7)
  9. ;(xl_exp '((0 . 1) 2 (3(4 . (5(6 7 "a" . 7)))))) -> (0 1 2 3 4 5 6 7 "a" 7)

但是,对
;(xl_exp '((0 . 1) 2 (3(4 . (5(6 7 "a . b" . 7)))))) -> (0 1 2 3 4 5 6 7 "a b" 7) 错误!
当然还可以进一步对“”判断,避免“号的内容被处理。但是可能还有其它情况呢?总是心里不踏实。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-26 22:38 , Processed in 0.228916 second(s), 60 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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