0

我在开发递归函数时遇到了麻烦,该函数将查看两个列表是否彼此相等,包括查看子列表。到目前为止,我有:

(defun are-equal2 (X Y)
(cond
    ((null X) nil)
    ((and (listp (first X)) (listp (first Y)))
        (are-equal2 (first X) (first Y))
    )
    ((eq (first X) (first Y))
        T                   
    )
)
)

它有时似乎有效。例如(are-equal2 '((A) B) '((A) B))返回 T 并(are-equal2 '((A) B) '(A B))返回 nil。但(are-equal2 '(F (A G) B) '(F (T G) B))返回 T ..... 我认为这可能与我的最后一个条件有关。我不知道如何重新工作。

没关系大声笑。做了一些修修补补等待答复并得到它。做了一堆嵌套的 if 语句。代码:

(defun are-equal2 (X Y)
    (if (and (listp (first X)) (listp (first Y)))
        (are-equal2 (first X) (first Y))
        (if (and (eq (first X) (first Y)))
            (if (and (endp (rest X)) (endp (rest Y)))
                T
                (are-equal2 (rest X) (rest Y))
            )
            nil
        )
    )

)

4

1 回答 1

2

我不认为你可以在这里使用尾递归版本。

恐怕您将不得不将您的论点视为,而不是序列

例如,

(defun are-equal (x y &key (test #'eql))
  (or (funcall test x y) 
      (and (consp x)
           (consp y)
           (are-equal (car x) (car y))
           (are-equal (cdr x) (cdr y)))))

这比较了默认情况下使用的叶子eql(参见有关测试功能的规则),而不是eq在您的示例中:

(are-equal '((1) a) '((1) a))
==> T
(are-equal '((1) a) '((1) b))
==> NIL
(are-equal '((1) a) '((2) a))
==> NIL
(are-equal '(("1") a) '(("1") a))
==> NIL
于 2013-09-29T15:08:26.350 回答