方案:如何检查列表的所有元素是否相同

时间:2011-09-06 13:19:07

标签: list lambda scheme equality

我想创建一个Scheme函数,如果传递一个完全由相同元素组成的列表,则会生成true。这样的清单将是'(1 1 1 1)。它会因为'(1 2 1 1)而产生错误。

这是我到目前为止所做的:

    (define (list-equal? lst)
      (define tmp (car lst))
      (for-each (lambda (x) 
                   (equal? x tmp))
                 lst)
      )

显然这是不正确的,我是新手。我想我无法表达我应该返回#t#f的步骤。

提前致谢!

编辑: 我摆弄了一下,找到了一个似乎运行良好的解决方案,只需要很少的代码:

(define (list-equal? lst)
 (andmap (lambda (x) 
        (equal? x (car lst)))
      lst))

再次感谢大家的帮助。

10 个答案:

答案 0 :(得分:3)

最少量的代码,如果你不在乎它只适用于数字:

(define (list-equel? lst)
  (apply = lst))

示例:

> (list-equel? '(1 1 2 1))
#f
> (list-equel? '(1 1 1 1))
#t
> (list-equel? '(1))
#t

答案 1 :(得分:1)

andmap解决方案很不错,但如果andmap不可用,您可以使用此解决方案。它使用基本操作(和,或者,空检查,等式检查)并处理空列表和一个元素列表。与Sean的实现类似,但不需要帮助定义。

(define (list-equal? args)
  (or (or (null? args)
          (null? (cdr args)))
      (and (eq? (car args) (cadr args))
           (list-equal? (cdr args)))))

答案 2 :(得分:0)

(define (list-equal? lst)
    (if (= (cdr lst) null)
        true
        (and (equal? (car lst) (cadr lst))
             (list-equal? (cdr lst)))))

答案 3 :(得分:0)

尝试这样的事情:

(define (list-equal? lst)
 (define (helper el lst)
  (or (null? lst)
      (and (eq? el (car lst))
           (helper (car lst) (cdr lst)))))
 (or (null? lst)
     (helper (car lst) (cdr lst))))

这可能不是最干净的实现,但我认为它将正确处理空列表和单元素列表的情况。

答案 4 :(得分:0)

在R6RS中有for-all函数,它接受谓词和列表,如果谓词对列表中的所有元素都返回true,则返回#t,否则返回#f正是你需要的。

因此,如果您使用的是R6RS(或具有for-all功能的任何其他方案方言),您只需在代码中将for-each替换为for-all即可。

答案 5 :(得分:0)

这样的事情应该有效:

(define (list-equal? lst)
  (cond ((< (length lst) 2) #t)
        (#t (and (equal? (car lst) (cadr lst))
             (list-equal? (cdr lst))))))

答案 6 :(得分:0)

这个帖子中的其他答案看起来都太复杂了(我仔细阅读了所有内容),所以这是我对它的看法:

(define (all-equal? lst)
  (define item (car lst))
  (let next ((lst (cdr lst)))
    (cond ((null? lst) #t)
          ((equal? item (car lst)) (next (cdr lst)))
          (else #f))))

(根据设计,它不适用于空列表。如果需要,可以轻松添加(if (null? lst) #t ...)。)

答案 7 :(得分:0)

一个简短的解决方案:

#lang racket
(define (all-equal? lst)
  (for/and
      ([i (in-permutations lst)])
    (equal? (first i) (second i))))

; TEST CASES

(require rackunit)

(check-false (all-equal? '(1 2 3)))
(check-true (all-equal? '(1 1 1)))
(check-true (all-equal? '()))

请注意,这会使用racket,因此这可能不适用于您的方案实施。

答案 8 :(得分:0)

另一个解决方案:

(define (all-same ls)
    (cond
     ((or (null? ls)
          (null? (cdr ls))) #t)
     (else (and (equal? (car ls) (next ls))
                (all-same (cdr ls)))))))

(define (next ls)
    (cond
     ((or (null? ls)
          (null? (cdr ls))) '())
     (else (cadr ls)))))

答案 9 :(得分:-1)

因为这些语言不好。尝试

(define list-equal?
 (lambda (lst)
   (if (= lst null)
   (true)
   (foldr = (car lst) (cdr lst))
)))