1

The little schemer のこのスクリプトを使用して、2 つのセットの交差を取得しています。しかし、「メンバー?」でバインドされていない識別子エラーが発生しています。何が問題なのか教えてください:

(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)) のような 2 つのリストを交差させたいのですが、それについての提案はありますか? この投稿から回答を探しています: 2 つのリストを取り、4 つのリストを返すスキーム関数を作成する方法

4

2 に答える 2

1

intersect1 を小文字の 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) 

シンボル以外のものを比較するには、 の代わりに をmember?使用するように変更する必要があります。次のようになります。equal?eq?

(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 と Scheme) では、member. 見つからない場合は (実装で false であるものは何でも) を使用equalして評価しfalse、見つかった場合は、要素が見つかった場所から始まる引数リストの残りの部分を評価します (これは true と見なされます)。

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

独自の述語の代わりに標準メンバーを使用する:

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

編集1

あなたは探しているのではintersectionなく、特別な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))
于 2013-08-08T15:51:55.683 に答える
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))]))
于 2013-08-09T00:24:49.840 に答える