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