Схема: как проверить, все ли элементы списка идентичны - PullRequest
5 голосов
/ 06 сентября 2011

Я хотел бы создать функцию Scheme, которая возвращает true, если ей передается список, который полностью состоит из идентичных элементов. Такой список будет «(1 1 1 1). Это приведет к false с чем-то вроде '(1 2 1 1).

Это то, что я имею до сих пор:

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

Очевидно, что это неправильно, и я новичок в этом. Я думаю, что не могу выразить шаг, на котором я должен вернуть #t или #f.

Заранее спасибо!

EDIT: Я немного поиграл и нашел решение, которое, кажется, работает очень хорошо и с минимальным количеством кода:

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

Еще раз спасибо за помощь всем.

Ответы [ 10 ]

3 голосов
/ 06 сентября 2011

Минимальный объем кода, если вам все равно, что он работает только для чисел:

(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 голос
/ 02 февраля 2014

Решение andmap хорошо, но если andmap недоступно, вы можете использовать это. Он использует основные операции (и, или, нулевая проверка, проверка равенства) и обрабатывает пустые списки и списки из одного элемента. Аналогичен реализации Шона, но определение помощника не требуется.

(define (list-equal? args)
  (or (or (null? args)
          (null? (cdr args)))
      (and (eq? (car args) (cadr args))
           (list-equal? (cdr args)))))
0 голосов
/ 12 ноября 2018

Еще одно решение:

(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)))))
0 голосов
/ 21 апреля 2016

Краткое, краткое решение:

#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? '()))

Обратите внимание, что здесь используется ракетка, поэтому это может не работать с реализацией вашей схемы.

0 голосов
/ 06 сентября 2011

Все остальные ответы в этой теме кажутся слишком сложными (я прочитал их все), так что вот мое мнение о них:

(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 ...)).

0 голосов
/ 06 сентября 2011

Примерно так должно работать:

(define (list-equal? lst)
  (cond ((< (length lst) 2) #t)
        (#t (and (equal? (car lst) (cadr lst))
             (list-equal? (cdr lst))))))
0 голосов
/ 06 сентября 2011

В R6RS есть функция for-all, которая принимает предикат и список и возвращает #t, если предикат возвращает true для всех элементов в списке, и #f в противном случае, что именно здесь вам нужно.

Таким образом, если вы используете R6RS (или любой другой диалект схемы, который имеет функцию for-all), вы можете просто заменить for-each на for-all в своем коде, и он будет работать.

0 голосов
/ 06 сентября 2011

Попробуйте что-то вроде этого:

(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))))

Возможно, это не самая чистая реализация, но я думаю, что она будет правильно обрабатывать случаи пустых списков и списков из одного элемента.

0 голосов
/ 06 сентября 2011

Ибо плохо на этих языках.Попробуйте

(define list-equal?
 (lambda (lst)
   (if (= lst null)
   (true)
   (foldr = (car lst) (cdr lst))
)))
0 голосов
/ 06 сентября 2011
(define (list-equal? lst)
    (if (= (cdr lst) null)
        true
        (and (equal? (car lst) (cadr lst))
             (list-equal? (cdr lst)))))
...