2011-09-06 1 views
4

전적으로 동일한 요소로 구성된 목록이 전달되면 true를 반환하는 Scheme 함수를 만들고 싶습니다. 그러한 목록은 '(1 1 1 1)이 될 것입니다. '(1 2 1 1)과 같이 거짓으로 나타납니다.Scheme : 목록의 모든 요소가 동일한 지 확인하는 방법

이것은 내가 지금까지 무엇을 가지고 :

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

다시 한번 감사의 도움말 모두.

답변

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

이것은 잘 작동하지 않는 것 같아요, 나는 그것이 끝까지 다가와 고독한 요소에 cadr을 사용할 수 없다고 불평한다고 생각합니다. 나는 이것이 라켓/Pretty Big을 사용하고 있습니다. – Joseph

+0

이것은 하나의 요소가있는 목록에서 폭발합니다. 편집 : 조셉, 맞습니다, 그것은 당신이 그것의 끝에 도착하면 어떤 목록에 날아 것이다. –

+0

@joseph : 네 말이 맞아. 방금 만든 작은 변화가 그것을 고쳐야합니다. – Daniel

-1

이 언어는 적합하지 않습니다. 이 같은

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

그건 작동하지 않습니다. 목록의 요소를 부울 결과와 비교합니다. – Daniel

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

가이되지 않을 수도 있습니다 깨끗한 구현,하지만 난 제대로 빈 목록 및 하나의 요소 목록의 경우를 처리 것이라 생각합니다. R6RS에서

+0

이것은 잘 작동합니다. 고마워, 나는 내가 이것에 매달렸다 고 생각한다. – Joseph

0

는 술어가 당신이 여기에서 필요로 정확히이다, 그렇지 않으면 모든 목록의 요소와 #f에 대해 true를 돌려주는 경우 #t을 술어와리스트를 받아, 반환 for-all 기능이있다.

따라서 R6RS (또는 for-all 기능이있는 다른 모든 스킴 방언)를 사용하는 경우 코드에서 for-eachfor-all으로 바꿔 사용해도됩니다.

+0

나를 위해 모든 것을 사용할 수 없다는 것이 너무 나쁘다. 그러나 내가 올바른 길을 가고 있었다는 것을 아는 것이 좋다. – Joseph

+0

추가 된 단계에서'lst'가 비어 있지 않은지 확인해야합니다. –

+0

@Sean : 예, 좋은 지적입니다. 즉,'tmp' 변수를 없애고 술어에서 매번'(car lst)'를 호출하면 (문제를 피하면서 결코 빈리스트를 호출하지 않을 것입니다). – sepp2k

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

(:

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

이것은 O (n *) 시간 대신 O (n * n) 시간에 실행된다는 점을 제외하면 매우 좋습니다. 목록의 각 위치에 대해 나머지 목록의 길이가 계산되기 때문입니다. 기본 케이스가'(또는 (null? lst) (null? (cdr lst)))''이되도록 조정하면 멋지고 간결할뿐만 아니라 런타임이 훨씬 향상됩니다. –

0

다른 답변을이 스레드에서 모든 (내가 그들 모두를 읽어) 너무 복잡한 것, 그래서 여기에 필자의 필요에 따라 (if (null? lst) #t ...)을 쉽게 추가 할 수 있습니다.)

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 
+0

확실히 최고의 솔루션이며, 나는 그것을 생각하지 않았다는 것을 믿을 수 없습니다. 잘 했어. – JasonFruit

+0

길이 조건이 필요하지 않지만. '(동일합니까?)'=>'# t' 인수없이. – JasonFruit

+0

목록이 숫자로만 구성된 경우에만 작동합니다. :-) –

1

andmap 솔루션은 좋은,하지만 andmap를 사용할 수없는 경우, 당신은이를 사용할 수 있습니다. 기본 조작 (및 또는 널 (Null) 점검, 항등 점검)을 사용하고 빈 목록 및 하나의 요소 목록을 처리합니다. Sean의 구현과 비슷하지만 도우미 정의가 필요하지 않습니다.

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

'(또는 1 2 3)'도 유효합니다. –

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

참고.