Lisp 在元素2之前插入元素1

Lisp 在元素2之前插入元素1,lisp,common-lisp,Lisp,Common Lisp,我有两个元素和一个列表。每次第一个元素出现在给定列表的第一级时,我都必须在第一个元素之前插入第二个元素 递归版本: (defun INSERT-ELEM (E1 E2 L) (cond ((null L) NIL) ((equal E1 (car L)) (cons E2 (INSERT-ELEM E1 E2 (cdr L)))) ((equal E2 (car L)) (cons E1 (INSERT-ELEM E1 E2 (cdr L))))

我有两个元素和一个列表。每次第一个元素出现在给定列表的第一级时,我都必须在第一个元素之前插入第二个元素

递归版本:

(defun INSERT-ELEM (E1 E2 L)
    (cond ((null L)  NIL)
       ((equal E1  (car L))  (cons E2 (INSERT-ELEM  E1 E2 (cdr L))))
       ((equal E2  (car L))  (cons E1 (INSERT-ELEM  E1 E2 (cdr L))))
       (t   (cons (car L) (INSERT-ELEM  E1 E2 (cdr L))))))
但有点不对劲,它改变了位置,而不是在E1前面插入E2。 有人能帮我吗?

有两个问题

首先,您只能在
E1
之前插入
E2
。但是这句话:

   ((equal E2  (car L))  (cons E1 (INSERT-ELEM  E1 E2 (cdr L))))
E2
之前插入
E1
。你应该把它去掉

第二个问题是,在进行递归调用时,结果中没有包含当前元素。因此,您正在删除所有
E1
元素。将递归调用更改为:

(list* e2 (car l) (insert-elem e1 e2 (cdr l)))
工作版本为:

(defun insert-elem (e1 e2 l)
  (cond ((null l)  nil)
        ((equal e1  (car l))  (list* e2 (car l) (insert-elem  e1 e2 (cdr l))))
        (t   (cons (car l) (insert-elem  e1 e2 (cdr l))))))

(insert-elem 'a 'b '(1 2 3 a c b d a b e))
=> (1 2 3 b a c b d b a b e)
变体,用于比较:

(defun insert-before (e1 e2 list)
  (loop
    for e in list
    when (equalp e e1)
      collect e2
    collect e))

(insert-before 1 0 '(5 4 1 2 1 3 5 1 1 2 3 5 7))
=> (5 4 0 1 2 0 1 3 5 0 1 0 1 2 3 5 7)
变体,为了好玩:

(defun insert-before (e1 e2 list)
  (mapcan (lambda (e)
            (if (equalp e e1)
              (list e2 e1)
              (list e)))
          list))

((相等的E2
开始的行执行相反的插入,它将
E1
放在
E2
之前。什么@Barmar?我不明白。非常感谢@Barmar.。这帮了大忙!