Racket在列表之间找到共享元素

时间:2016-12-09 00:45:13

标签: scheme racket

如果它与另一个列表共享元素,我试图为给定列表创建特定响应。如果我有一个列表(我的名字是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)))))

我非常了解球拍和计划但是我还没有真正把它编译好,所以我觉得我很大程度上不在。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

如果您的任务是找到 a (a b c)的成员,

,则不需要使问题复杂化

这是一段 Scheme 代码,可以判断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)

修改

我建议您阅读The Little SchemerThe Seasoned Schemer以更熟悉这些概念

答案 1 :(得分:1)

还可以使用内置函数filtermember来查找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的顺序是交换的,那么仅仅避免使用remove-duplicates可能会导致不同的结果。如果想要重复的元素在结果列表中重复出现,可以使用以下函数来删除常用项目:

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

答案 2 :(得分:1)

Why not use set in racket:

(define (list-intersect-2 lst1 lst2)
  (set->list
   (set-intersect (list->set lst1)
                  (list->set lst2))))

For a solution that takes one or more lists:

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