找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2877|回复: 23

[讨论]:有没有更好的方法简化这个函数?

[复制链接]
发表于 2005-10-6 15:43:20 | 显示全部楼层 |阅读模式

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

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

×

  1.   [FONT=courier new]
  2. ;;;调用方法->(dnr  n 列表)->可返回该列表删除第N个元素后,剩下的列表
  3. (defun dnr (n xlist / 1list nlist1 nlist2 nn n_add)
  4.   (setq n_add 0)                        ;设置一个递增的起始值
  5.   (setq nlist1 '())                        ;先设置一个空的子列表
  6.   (repeat (1- n)                ;循环(n-1)次得到所须的子列表
  7.     (setq 1list (nth n_add xlist))        ;提取0到N-1的每一个元素
  8.     (setq nlist1 (cons 1list nlist1))        ;将提取到的元素加入子列表
  9.     (setq n_add (1+ n_add))                ;使起始值递增
  10.   )
  11.   (setq nlist1 (reverse nlist1));返回倒置的子列表
  12.   ;;-----------------------------
  13.   (setq n_add n)                        ;设置一个递增的起始值
  14.   (setq nlist2 '())                        ;先设置一个空的子列表
  15.   (setq nn (- (length xlist) n));返回第N个元素以后的元素数量
  16.   (repeat nn                ;循环nn次得到所须的子列表
  17.     (setq 1list (nth n_add xlist))        ;提取n+1到以后的每一个元素
  18.     (setq nlist2 (cons 1list nlist2))        ;将提取到的元素加入子列表
  19.     (setq n_add (1+ n_add))                ;使起始值递增
  20.   )
  21.   (setq nlist2 (reverse nlist2));返回倒置的子列表
  22.   (append nlist1 nlist2);连接为新表
  23.   
  24. )

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

已领礼包: 8157个

财富等级: 富甲天下

发表于 2005-10-6 16:45:22 | 显示全部楼层
  1. ;;; HEAD - list of only the first n elements
  2.      ;;; (including) the n-th element, base 1
  3.      ;;; (head l 0) ==> nil
  4.      ;;; (head l 1) ==> first element

  5.     (defun head (l n) (head-rek l nil n))
  6.     (defun head-rek (l x n)
  7.        (cond ((zerop n) (reverse x))
  8.              (t (head-rek (cdr l) (cons (car l) x) (1- n)))
  9.        )
  10.     )

  11.      ;;; TAIL - list l without the first n elements

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

使用道具 举报

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

使用道具 举报

发表于 2005-10-6 17:54:35 | 显示全部楼层
下面是思路很直接的一种,效率不高,stdlib里面有一种二分法搜索的,不过我看的有点晕
[php]
(defun dnr (n xlist / 1list nlist1 nlist2 nn n_add)
  (setq n_add 0)                       
  (setq nlist1 '())       
  (repeat (length xlist)               
    (cond ((/= n_add n)
    (setq nlist1 (append nlist1 (list (nth n_add xlist))))
    ))
    (setq n_add (1+ n_add))
  )
  nlist1
  )
[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

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

使用道具 举报

发表于 2005-10-6 21:17:15 | 显示全部楼层
  1. [FONT=courier new];;;返回删除列表中第n个元素后的列表
  2. ;;;(dnr n 列表)
  3. ;;;(dnr 8 '((1 2) (2 3) (3 4) (4 5) (5 6) (6 7)))→((1 2) (2 3) (3 4) (4 5) (6 7))
  4. ;;;(dnr 4 '((1 2) (2 3) (3 4) (4 5) (5 6) (6 7)))→((1 2) (2 3) (3 4) (5 6) (6 7))

  5. (defun dnr (n xlist / l1)
  6.   (if (<= n (length xlist))
  7.     (progn
  8.       (setq l1 '())
  9.       (repeat (- n 1)
  10.         (setq l1    (cons (car xlist) l1)
  11.               xlist (cdr xlist)
  12.         )
  13.       )
  14.       (setq l1 (append (reverse l1) (cdr xlist))
  15.             xlist l1
  16.       )      
  17.     )
  18.   )
  19.   xlist
  20. )[/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-10-6 23:08:05 | 显示全部楼层 |阅读模式

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

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

×
;; 想的简单一点行不?

  1.   [FONT=courier new]
  2. ;; 表删除第i项元素
  3. ;;(xl-xi '(0 1 2 3 4 5) 3) -> (0 1 2 4 5)
  4. (defun xl-xi (l n / i)
  5.   (setq i -1)
  6.   (apply 'append
  7.          (mapcar '(lambda (x)
  8.                     (setq i (1+ i))
  9.                     (if        (= i n) nil(list x))
  10.                   )
  11.                  l
  12.          )
  13.   )
  14. )
  15.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2005-10-7 00:05:39 | 显示全部楼层
最初由 狂刀 发布
[B];; 想的简单一点行不?
;; 表删除第i项元素
;;(xl-xi '(0 1 2 3 4 5) 3) -> (0 1 2 4 5)
(defun xl-xi (l n / i)
  (setq i -1)
  (apply 'append
         (mapcar '(lambda (x)
                ... [/B]


够简洁。
(setq i -1)有误!
  1. [FONT=courier new](defun xl-xi (l n / i)
  2.   (setq i 0)
  3.   (apply 'append
  4.          (mapcar '(lambda (x)
  5.                     (setq i (1+ i))
  6.                     (if        (= i n) nil (list x)))
  7.                  l
  8.          )))[/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-10-7 00:27:07 | 显示全部楼层
(setq i -1)
无误!
因为一开始mapcar就 (setq i (1+ i)),因此 i 是从 0 起算的,与lisp的习惯相符
这也能从测试 ;;(xl-xi '(0 1 2 3 4 5) 3) -> (0 1 2 4 5)  体现出
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-10-7 09:05:47 | 显示全部楼层
最初由 狂刀 发布
[B](setq i -1)
无误!
因为一开始mapcar就 (setq i (1+ i)),因此 i 是从 0 起算的,与lisp的习惯相符
这也能从测试 ;;(xl-xi '(0 1 2 3 4 5) 3) -> (0 1 2 4 5)  体现出 [/B]

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

使用道具 举报

 楼主| 发表于 2005-10-7 09:32:17 | 显示全部楼层
我简单的解释了一下,请大家指教

  1.   [FONT=courier new]
  2. ;;;调用方法->(dnr  列表 n)->可返回该列表删除第N个元素后,剩下的列表
  3. (defun xl-xi (l n / i)
  4.   (setq i 0);设置初始值
  5.   (apply 'append
  6.          (mapcar '(lambda (x)
  7.                     (setq i (1+ i));每代入一次,增数i+1,使i始终与n保持一致
  8.                     (if        (= i n)
  9.                       nil
  10.                       (list x)
  11.                     );当遇到第N个元素时,返回NIL,否则返回本身
  12.                   );设置一个匿名函数,以X为自变量
  13.                  l
  14.          );将列表中每一个元素代入到上面的匿名函数,返回一组新列表
  15.   );把所有列表结合成一个单一列表
  16. )
  17.   [/FONT]

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

使用道具 举报

发表于 2005-10-7 09:39:22 | 显示全部楼层
回xyp,为免发生歧意,对表项的计数均从0起算,其实lisp都是这个规则。对表长度、选集及字符的计数才从1起算。

  1.   [FONT=courier new]
  2. nth
  3. 语法
  4.      (nth n list)
  5. 功能及参数
  6.      此函数将返回 list 中的第 n 个元素, 其中 n 是返回元素的顺序号码 (第一个元素由零开始的)。如果 n 的数目超过 list 中的数目时, 本函数将返回 nil。
  7. 范例
  8.     (nth 3 '(a b c d e))              返回             D
  9.   [/FONT]
复制代码


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

使用道具 举报

 楼主| 发表于 2005-10-7 10:25:18 | 显示全部楼层
最初由 xyp1964 发布
[B][];;;返回删除列表中第n个元素后的列表
;;;(dnr n 列表)
;;;(dnr 8 '((1 2) (2 3) (3 4) (4 5) (5 6) (6 7)))→((1 2) (2 3) (3 4) (4 5) (6 7))

(defun dnr (n xlist / l1)
  (if (<= ... [/B]

版主的函数我也简单的解释一下,不对之处请多指教

  1.   [FONT=courier new]
  2. (defun dnr (n xlist / l1)
  3.   (if (<= n (length xlist));判断数N有没有超过表的长度
  4.     (progn
  5.       (setq l1 '());设置一个空表
  6.       (repeat (- n 1);循环执行N-1次
  7.         (setq l1    (cons (car xlist) l1);依次将XLIST中的第一项加入到l1中
  8.               xlist (cdr xlist);依次除去xlist中第一个元素
  9.         )
  10.       )
  11.       (setq l1          (append (reverse l1) (cdr xlist));连接N前面与后面的元素
  12.             xlist l1
  13.       );将结果返还给xlist
  14.     )
  15.   )
  16.   xlist
  17. )
  18.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-10-7 12:44:47 | 显示全部楼层
我有点困惑
为什么不是
;;;(dnr 8 '((1 2) (2 3) (3 4) (4 5) (5 6) (6 7)))→((1 2) (2 3) (3 4) (4 5) (6 6) 7)

;;;(dnr 8 '((1 2) (2 3) (3 4) (4 5) (5 6) (6 7)))→((1 2) (2 3) (3 4) (5 6) (6 7))

而是
;;;(dnr 8 '((1 2) (2 3) (3 4) (4 5) (5 6) (6 7)))→((1 2) (2 3) (3 4) (4 5) (6 7))
好像不宜理解
是不是应该为“删除炸开表的第n个元素对应的原表所在元素后的一个元素”
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2005-10-7 14:04:12 | 显示全部楼层
最初由 狂刀 发布
[B]回xyp,为免发生歧意,对表项的计数均从0起算,其实lisp都是这个规则。对表长度、选集及字符的计数才从1起算。

nth
语法
     (nth n list)
功能及参数
     此函数将... [/B]

理论上没错,但不符合用户的通常习惯。
谁能理解表(1 2 3 4 5 6 7 8)中的第4项不是4反而是5呢?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-28 15:57 , Processed in 0.218881 second(s), 62 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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