lisp - 删除列表中包含列表的元素

标签 lisp

这里是 LISP 的初学者。我正在为即将到来的 LISP 考试做准备,我遇到了一个我无法解决的问题,所以我希望更有经验的人可以帮助我。

无论如何,这是我的问题: 您将获得一个列表,其中可能包含列表作为元素。您的任务是删除给定位置的原子元素。

列表和位置作为输入参数给出。

示例:Position=5 , List=(1 (2 3) ((4)) (5 (6))) ,应该返回 (1 (2 3) ((4)) ((6)))。

这是我到目前为止得到的...(PS 由于 imMaw 的帮助,下面的代码可以工作,您可以检查编辑以查看我之前的错误)。

(defun number_of_atoms(List)
 (atoms List 0)
)
(defun atoms(List Number)
 (cond
  ((null List) Number)
  ((atom (car List)) (atoms (cdr List) (+ 1 Number)))
  ((+ (atoms (car List) Number) (atoms (cdr List) 0)))
 )
)
(defun deleteElement(Pos List)
 (deleteElementAcc Pos 1 List)
)
(defun deleteElementAcc(Pos CurrPos List)
(cond 
  ((null List) nil)
  ((and (atom (car List)) (not(eql CurrPos Pos))) (cons (car List) (deleteElementAcc Pos (+ CurrPos 1) (cdr List))))
  ((and (atom (car List)) (eql CurrPos Pos)) (deleteElementAcc Pos (+ CurrPos 1) (cdr List)))
  ((cons (deleteElementAcc Pos CurrPos (car List))
         (deleteElementAcc Pos (+ CurrPos (number_of_atoms(car List))) (cdr List))))
)
)

最佳答案

为什么在一半的地方用 z 拼写 Pos 和 CurrPos?

而你的代码中的问题在于 cond 的最后一个分支。在List的cdr上递归时,CurrPos需要提前(car List)中的元素个数。而一个简单的(长度列表)是行不通的,因为它需要递归地计算子列表中的元素。

编辑:更多细节 假设我们打电话

(deleteElement 3 '((1 2) (3 4)))  

你把它变成

(deleteElementPos 3 1 '((1 2) (3 4))),

它落入 cond 的最后一个 case,你得到

(cons (deleteElementAcc 3 1 '(1 2))
      (deleteElementAcc 3 1 '((3 4))))

注意 currPos 对于列表的 cdr 是错误的 - 它应该是 3,而不是 1。你实际上希望你的代码变成

(cons (deleteElementAcc 3 1 '(1 2))
      (deleteElementAcc 3 (+ 1 2) '((3 4))))

因为 (car List) 中有 2 个元素。

所以,你只需要改变

(deleteElementAcc Pos CurrPos (cdr List))

进入

(deleteElementAcc Pos (+ CurrPos (recursive-length (car List))) (cdr List))

和程序递归长度,这是一个非常简单的函数。它应该计算子列表中的元素,例如 (recursive-length '((1 2) ((3)))) 返回 3。

关于lisp - 删除列表中包含列表的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13612960/

相关文章:

recursion - 我通过小 lisper 工作。纬度函数?检查列表的所有元素是否都是原子

lisp - 获取用户创建的变量列表

web - 如何创建 Restas 全局装饰器

lisp - 从列表中删除元素

documentation - 有人知道比较不同 Scheme 实现的好文档吗?

windows-vista - SBCL 在 Vista 上崩溃。你知道如何让它发挥作用吗?

lisp - lisp 函数可以返回引用或通过引用接收参数吗?

emacs - 将光标定位在初始化重新绑定(bind)宏中

emacs - 通过 cl 函数传递回调

lisp - Common Lisp 和 Scheme 词法闭包的区别