为什么下面的lisp代码没有给出期望的结果

  • 本文关键字:结果 期望 lisp 代码 lisp
  • 更新时间 :
  • 英文 :


我有一个列表

'((1 2 (A B C)) (2 3 (B C D)) (4 5 (C D F)))

我想处理内部列表中的元素,(在本例中,我想将(A B C)和其他列表更改为(M M M))。

我写了一个代码(process lst),它将为内部列表执行此任务。

(defun process (lst)
(cond
((null lst) '())
(T (cons 'M (process (cdr last))))))

当我从main函数调用时,

(defun iterate-list (lst)
(cond
((null lst) '())
((listp (car lst)) 
(cons (process (car lst)) 
(iterate-list (cdr lst))))
(T 
(cons (car lst) 
(iterate-list (cdr lst))))))

我得到的是((M M M) (M M M) (M M M))而不是((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M)))

但是当我使用相同的函数时,在第二个条件(listp (car lst))中只有(cons (car lst)) (iterate-list (cdr lst))),我得到了正确的答案,即

'((1 2 (A B C)) (2 3 (B C D)) (4 5 (C D F)))

我不知道我在哪里出错了。

如果你想要一些实用的,我建议从Common LISP Standard Library.

subst

函数。http://clhs.lisp.se/Body/f_substc.htm

(setq tree1 '(1 (1 2) (1 2 3) (1 2 3 4))) =>  (1 (1 2) (1 2 3) (1 2 3 4))
(subst "two" 2 tree1) =>  (1 (1 "two") (1 "two" 3) (1 "two" 3 4))
(subst "five" 5 tree1) =>  (1 (1 2) (1 2 3) (1 2 3 4))

您还可以通过使用带有lambda函数的变体subst-if来添加您自己的相等函数。

需要将process中的last重命名为lst

我得到((M M M M) (M M M M) (M M M M))而不是((1 2 (M M M M)) (2 3 (M M M M))) (4 5 (M M M M))

代码可以工作,但不是在你想要的深度:

(process '(a b c d))
=> (M M M M)
(iterate-list '(1 2 (A B C)))
=> (1 2 (M M M))

为了处理根列表中的所有列表,您可以这样做:

(mapcar #'iterate-list '((1 2 (A B C))
(2 3 (B C D))
(4 5 (C D F))))
=> ((1 2 (M M M)) (2 3 (M M M)) (4 5 (M M M)))

最新更新