我想用Common Lisp

时间:2016-04-08 10:52:01

标签: lisp common-lisp

我想使用Common Lisp合并和排序两个已排序的关联列表。 我做了代码。但结果与我的想法不一样。

(defun MERGEALIST (K L)
  (cond ((and (eq nil K) (eq nil L)) nil)
        ((eq nil K) L)
        ((eq nil L) K)
        ((<= (car (car K)) (car (car L)))
         (cons K (MERGEALIST (cdr K) L)))
        ((> (car (car K)) (car (car L)))
         (cons L (MERGEALIST K (cdr L))))))

功能输入KL是已排序的关联列表。 例如,

K((1 . a) (3 . c) (5 . e))

L((2 . b) (4 . d))

我预计结果为((1 . a) (2 . b) (3 . c) (4 . d) (5 . e))

但结果完全不同。 为什么会出现这个结果? 感谢。

2 个答案:

答案 0 :(得分:2)

你可以稍微简化一下。主要的变化就像是jkiiski的评论。

CL-USER 5 > (defun MERGEALIST (K L)
              (cond ((and (null K) (null L)) nil)
                    ((null K) L)
                    ((null L) K)
                    ((<= (caar K) (caar L))
                     (cons (car K) (MERGEALIST (cdr K) L)))
                    ((> (caar K) (caar L))
                     (cons (car L) (MERGEALIST K (cdr L))))))
MERGEALIST

CL-USER 6 > (mergealist '((1 . a) (3 . c) (5 . e)) '((2 . b) (4 . d)))
((1 . A) (2 . B) (3 . C) (4 . D) (5 . E))

内置函数merge可以做到:

CL-USER 9 > (merge 'list
                   '((1 . a) (3 . c) (5 . e))
                   '((2 . b) (4 . d))
                   #'<
                   :key #'car)
((1 . A) (2 . B) (3 . C) (4 . D) (5 . E))

答案 1 :(得分:0)

(cons K (MERGEALIST (cdr K) L))

在这里,您将完整的列表K放在计算的“休息”之前。你只需要它的第一个元素(你刚刚测试过“来到”L的第一个元素):

(cons (car K) (MERGEALIST (cdr K) L))

虽然请注意你可以简化很多:

(defun merge-alists (k l)
  (cond 
    ;; Common case first, if both alists are not empty, then select
    ;; the first element of that alist, whose car is less. Then, recurse.
    ((and (consp k) (consp l))
         (if (<= (caar k) (caar l))
           (cons (car k) (merge-alists (cdr k) l))
           (cons (car l) (merge-alists k (cdr l)))))
    ;; One of the alists is empty, use either the not-empty one or ...
    ((consp k) k)
    ;; ... just the other (when k is empty or both are empty)
    (t l)))

(最后两个cond条款可以简化为(t (or k l)) ......但这可能有点过于简洁,无法清楚理解。)

或者,正如已经指出的那样,使用merge