2013-08-08 1 views
1

작은 스케커에서이 스크립트를 사용하여 두 세트의 교차를 가져옵니다. 하지만에 결합되지 않은 식별자 오류가 발생하고, 사람이 뭐가 잘못 됐는지 알려주세요 수있는 '회원이 아니세요?'체계에서 두 목록의 쌍 교차를 가져 오는 방법은 무엇입니까?

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

내가 위의이 기능을 잃어버린 : 또한

(define member? 
    (lambda (a lat) 
    (cond ((null? lat) #f) 
      (else (or (eq? (car lat) a) 
        (member? a (cdr lat))))))) 

, 나는이 교차 할 '((1 2) (2 7))'((1 3) (4 5)) = '((1 5)), 그것에 대해 어떤 제안이 있습니까? 이 게시물에서 답을 찾고 있어요 : How to write a scheme function that takes two lists and returns four lists

+0

은 ((1 5))'I가 생각하고 –

+0

두 번째 목록의 각 쌍의 첫 번째 요소가있는 첫 번째 목록의 각 쌍의 첫 번째 요소를 비교 한 다음 일치하는 경우 두 번째 요소를 추가합니다. :/ –

+1

당신은 그 행동에 대해 확신합니다. (1 2) (3 4) (5 6)) '((9 10) (7 8) (5 6)))) = => ((5 6))'는 교차점과 프로 시저의 동작에 대한 올바른 이해입니다. 당신의'회원?'은'eq '대신에'equal?'을 사용할 필요가 있습니다. – Sylwester

답변

1

당신은 당신이 문자를 비교하는 경우 intersect 날에 의해 잘 보인다 수정 경우 소문자 L.으로 함께 일을 전환 한 intersect에 오타가 있습니다. 예 : 이 문자보다 다른 일을 비교 만들려면

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

(intersect '(a b c d) '(c d e f)) ; ==> (c d) 

, 당신은 equal? 대신 eq? 사용하므로 member?을 변경해야합니다. 그것은 다음과 같습니다 :

(define member? 
    (lambda (a lat) 
    (cond 
     ((null? lat) #f) 
     (else (or (equal? (car lat) a) ; changed eq? to equal? 
       (member? a (cdr lat))))))) 

(intersect '((1 2)(3 4)(5 6)) '((9 10) (7 8) (5 6))) ; ==> ((5 6)) 

이 후에도. 위의 기호 버전은 여전히 ​​작동합니다. 적어도 LISP (Common Lisp and Scheme)에는 member이 있습니다. equal을 사용하고 false (구현에서 false 임)을 찾지 못하면 요소가 발견 된 곳부터 시작하여 나머지 인수 목록을 평가합니다 (사실이라고 판단되는 경우) :

(member 'a '(x y a c)) ; ==> (a c) 
1

그것은 당신이검색되지 않는 것 같다

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

(intersect '((1 2)(3 4)(5 6)) '((9 10) (7 8) (5 6))) ; ==> ((5 6)) 
(intersect '(a b c d) '(c d e f)) ; ==> (c d) 

편집 : 대신에 자신의 술어의 표준 멤버를 사용

하지만 특별한 alist 병합 :

#!r6rs 
(import (rnrs base) 
     (rnrs lists)) 

;; if you dont have r6rs remove the above and 
;; uncomment this rnrs/lists-6 memp 
#;(define (memp predicate? lst) 
    (cond ((null? lst) #f) 
     ((predicate? lst) lst) 
     (else (memp predicate? (cdr lst))))) 


(define (alist-merge merge-proc alist-1 alist-2) 
    (if (null? alist-1) 
     '() 
     (let* ((name (caar alist-1)) 
      (found (memp (lambda (x) (equal? (car x) name)) alist-2))) 
     (if found 
      (cons (merge-proc (car alist-1) (car found)) 
        (alist-merge merge-proc 
           (cdr alist-1) 
           alist-2)) 
      (alist-merge merge-proc 
         (cdr alist-1) 
         alist-2))))) 

(define (alist-merge-add alist-1 alist-2) 
    (alist-merge (lambda (x y) 
       (list (car x) 
         (+ (cadr x) (cadr y)))) 
       alist-1 
       alist-2)) 

(alist-merge-add '((1 2)(2 7)) '((1 3)(4 5))) ; ==> ((1 5)) 
+0

정확한 쌍을 확인합니다. . :/쌍의 첫 번째 요소를 확인하고 두 번째 요소를 추가해야합니다. 감사. –

+1

@ user2662909 ** ** 교차로가 아닙니다.나는 당신이 원하는 것을 수행하는 일반적인'alist-merge'와'alist-merge-add'를 추가했습니다. – Sylwester

0

내 교차로 솔루션 : 그것은 '그 두 목록은`생산하는 "교차"어떻게 명확하지

#lang racket 
(define (intersect set1 set2) 
    (cond [(empty? set1) '()] 
     [(empty? set2) '()] 

     [(= (caar set1) (caar set2)) (cons (list (caar set1) 
               (+ (cadar set1) 
                (cadar set2))) 
              (intersect (cdr set1) (cdr set2)))] 
     [(< (caar set1) (caar set2)) (intersect (cdr set1) set2)] 
     [else (intersect set1 (cdr set2))]))