Scheme Racket查找列表之间的共享元素

Scheme Racket查找列表之间的共享元素,scheme,racket,Scheme,Racket,如果给定列表与另一个列表共享元素,我将尝试为该列表创建一个特定的响应。如果我有一个列表(我的名字是John)和另一个列表(John Adam Jacob),我希望第一个列表能够看到John在第二个列表中,并且能够打印出(这是一个已知的名字)或类似的内容 我想到的代码使用map和member (define (specific-reply user-list) (cond (member (map (lambda (user-list)) '(John Adam Jacob)))

如果给定列表与另一个列表共享元素,我将尝试为该列表创建一个特定的响应。如果我有一个列表(我的名字是John)和另一个列表(John Adam Jacob),我希望第一个列表能够看到John在第二个列表中,并且能够打印出(这是一个已知的名字)或类似的内容

我想到的代码使用map和member

(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)))))
然而,我对racket和scheme都非常了解,而且我还没有真正将其编译出来,所以我想我基本上已经离开了


任何帮助都将不胜感激。

如果您的任务只是查找a是否是
(a b c)
的成员,则无需将问题复杂化

下面是一段方案代码,可以判断
a
是否是
lat
的成员。 它只是一个简单的递归函数,用于将lat的每个元素与a进行比较,以获得匹配

(define member?
    (lambda (a lat)
        (cond
            ((null? lat) #f)
            ((eq? a lat) #t)
            (else
                 (member? a (cdr lat))))))
如果你想更进一步,找到两个列表的交集,我们可以这样做

(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))))
您可以这样使用此代码。从guile编译器测试

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

>> (1 2)
编辑


我建议您阅读并熟悉这类概念

还可以使用内置函数
过滤器
成员
查找两个列表的交集:

(define (intersection l1 l2)
  (remove-duplicates
   (filter (λ (x) (member x l1))  
           l2)))
以上检查l2的每个项目,仅当它也是l1的成员时才保留它

还可以使用
for/list
检查每个元素并返回常用项列表:

(define (intersect l1 l2)
  (remove-duplicates
   (for/list ((i l1)
              #:when (member i l2))
     i)))
上述两个函数都可以删除重复项。如果仅将l1和l2的顺序互换,则仅避免使用“删除重复项”
,可能会导致不同的结果。如果希望重复的元素在结果列表中重复出现,可以使用以下函数,在继续之前删除常用项:

(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)
为什么不在球拍中使用:

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

成员
不是高阶函数(至少在没有可选的第三个参数的情况下使用时不是)。