2016-12-09 1 views
2

다른 목록과 요소를 공유하는 경우 주어진 목록에 대한 특정 응답을 만들려고합니다. 마찬가지로 (My name is John) 목록이 있고 (John Adam Jacob) 다른 목록이있는 경우 첫 번째 목록에서 John이 두 번째 목록에 있음을보고 인쇄 할 수 있어야합니다. (이것은 알려진 이름입니다.) 또는 유사한 것의 라인을 따라 무엇인가.Racket은 목록간에 공유 요소를 찾습니다.

지도를 사용하여 생각한 코드와 회원.

(define (specific-reply user-list) 
    (cond (member (map (lambda (user-list)) '(John Adam Jacob))) 
      (write (this is a known name)) 
     (else 
      (write (this is not a known name))))) 

나는 매우 그러나 라켓과 계획 모두 알고 그리고 난 정말 그렇게 내가 크게 떨어져라고 생각 아직 컴파일 못 했어.

도움을 주시면 감사하겠습니다. 당신은 당신의 작업이 (a b c)의 구성원 인 경우 만 찾을 경우 문제를 복잡하게 할 필요가 없습니다

답변

2

, 여기

a 경우 알 수 계획 코드 조각의가 구성원 인 lat입니다. 위의 각 요소를 a와 a로 비교하는 단순한 재귀 함수입니다.

더 자세히 살펴보고 두 목록의 교차점을 찾으려면 다음과 같이하십시오.

(define intersect 
    (lambda (set1 set2) 
      (letrec 
       ((I (lambda (set) 
         (cond 
          ((null? set) (quote())) 
          ((member? (car set) set2) 
          (cons (car set) 
            (I (cdr set)))) 
          (else (I (cdr set))))))) 
      (I set1)))) 

이 코드를 그대로 사용할 수 있습니다. 교활 컴파일러

(begin 
     (display (intersect `(1 2 3) `(1 3 4 5 2))) 
     (newline)) 

>> (1 2) 

편집 난 당신이 The Little Schemer 읽어 보는 것이 좋습니다

The Seasoned Schemer에서 테스트하는 개념

1

하나를 사용할 수도 있습니다 내장 함수 filter 이런 종류의에 익숙해 얻을 수 member 목록의 교차점을 찾으려면

(define (intersection l1 l2) 
    (remove-duplicates 
    (filter (λ (x) (member x l1)) 
      l2))) 

위의 내용은 l2의 각 항목을 검사하여 l1의 구성원 인 경우에만 유지합니다.

(define (intersect l1 l2) 
    (remove-duplicates 
    (for/list ((i l1) 
       #:when (member i l2)) 
    i))) 

모두 위의 기능 중복을 제거 :

하나는 일반적인 항목의 목록을 각 요소를 확인하고 반환 for/list를 사용할 수 있습니다. remove-duplicates의 사용을 피하면 단순히 l1과 l2의 순서가 interchaged되면 ​​다른 결과가 발생할 수 있습니다.

(define (intersection2 l1 l2) 
    (let loop ((l1 l1) 
      (l2 l2) 
      (ol '())) 
    (cond 
     [(empty? l1) (reverse ol)] 
     [(member (first l1) l2)  ; first item of l1 is common 
     (loop (rest l1)    ; loop with rest of l1 
      (remove (first l1) l2) ; remove common item from l2 
      (cons (first l1) ol))] ; add common item to outlist 
     [else 
     (loop (rest l1) 
      l2 
      ol)]))) 

테스트 :

(intersection2 '(2 4 2 7 2 10) '(10 2 9 2 0 11)) 

출력 :

'(2 2 10) 
하나는 반복 요소가 결과 목록에서 반복적으로 올 것을 원한다면, 하나는 일반적인 항목을 계속하기 전에 제거하는 다음과 같은 기능을 사용할 수 있습니다
+0

는'member'는 (적어도 그 옵션 3 인수없이 사용되지 않음) 고차 함수가 아닙니다. –

+0

나는이 진술을 수정했다. – rnso

1

라켓에 set을 사용하지 않는 이유 :

(define (list-intersect-2 lst1 lst2) 
    (set->list 
    (set-intersect (list->set lst1) 
        (list->set lst2)))) 
하나 개 이상의 목록 소요 해결책을

:

(define (list-intersect lst1 . lstn) 
    (set->list 
    (foldl set-intersect 
      (list->set lst1) 
      (map list->set lstn)))) 


(list-intersect '(1 2 3) '(2 3 4) '(3 4 8)) 
; ==> (3)