为什么下面的 lisp 代码没有给出预期的结果
Why the below lisp code is not giving desired result
我有一个列表
'((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))))))
当我从主函数调用时,
(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
I am getting ((M M M) (M M M) (M M M)) instead of ((1 2 (M M M)) (2 3 (M M M)) (4 5 (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)))
我有一个列表
'((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))))))
当我从主函数调用时,
(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
I am getting ((M M M) (M M M) (M M M)) instead of ((1 2 (M M M)) (2 3 (M M M)) (4 5 (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)))