1

我正在使用 The little schemer 中的这个脚本来获得两组的交集。但是我在“成员?”处收到未绑定的标识符错误,谁能告诉它有什么问题:

(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)),关于如何去做的任何建议?我正在从这篇文章中查找答案:如何编写一个采用两个列表并返回四个列表的方案函数

4

2 回答 2

1

intersect您在将 1 切换为小写 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. 它在未找到时使用equal并评估为false(在实现中为假),如果找到,则从找到元素的位置开始评估参数列表的其余部分(这被认为是真的):

(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 回答