如何检查列表中的所有元素是否相等?

时间:2019-10-12 05:11:19

标签: common-lisp

这是我到目前为止所得到的,但这只是比较第一个元素和第二个元素。因此,如果我评估此(检查'(a a a a a)),它应该返回true;但是,如果我评估?(检查'(a a a a b)),它应该返回Nil

(defun check (lista)
(cond
((null lista)'())
((equal (car lista)(cadr lista))cdr lista)
(t(check (cdr lista)))))

3 个答案:

答案 0 :(得分:3)

我不确定这是否是最惯用的方式,但是我会从这样的内容开始

CL-USER> (let* ((list '(a a a a))
                (first-element (first list)))
           (every (lambda (x) (equal x first-element)) list))
T
CL-USER> (let* ((list '(a a a b))
                (first-element (first list)))
           (every (lambda (x) (equal x first-element)) list))
NIL

答案 1 :(得分:2)

一些评论:

  • 缩进代码以提高可读性
  • 检查列表中只有一个元素的情况
  • 当第一个元素和第二个元素不同时,您可以递归调用函数,但是在这种情况下,您不需要它,因为已知该属性为false。

您的尝试几乎是好的,您只将递归调用放在错误的位置。相等是可传递的,因此您只需要比较每个元素及其后继元素,并查看该属性是否适合子列表。我个人将其编写如下:

(defun all-equal-p (list)
  (or (null (rest list)) ;; singleton/empty
      (and (equalp (first list)
                   (second list))
           (all-equal-p (rest list)))))

答案 2 :(得分:2)

除了练习之外,最简洁的检查形式是

(every #'eql list (rest list))

Every接受一个函数并将其应用于以下每个序列的一个元素,该序列可以是该函数接受的任何数字。因此,此调用将比较每两个连续的元素。