从列表中返回未包含在另一个列表中的元素

时间:2013-10-25 20:14:38

标签: list scheme racket

您好我想写一个简单的函数,它接受2个列表并返回第一个列表中未包含在另一个列表中的元素。

例如l1'(1 2 3 4)l2'(5 6 2 8 3)

回报应为'(1 4)

目前,我有这段代码:

(define (iteration2)
    (define listA '())
    (for ([list1 a])
        (for ([list2 b])
          (if (equal? list1 list2)
              '()
              (cons list1 listA))))
    listA) 

感谢

2 个答案:

答案 0 :(得分:2)

在编写循环(或递归)之前,始终建议查看其中一个内置函数是否可以为您执行循环。在您的情况下,您想要过滤列表,所以:

(define (first-not-second l1 l2)
  (filter 
   (lambda (x) (not (member x l2))) 
   l1))

,例如

(first-not-second '(1 2 3 4) '(5 6 2 8 3))
=> '(1 4)

Racket for版本将是

(define (first-not-second l1 l2)
  (for/list ((x l1) #:unless (member x l2))
    x))

和经典的“辅助函数样式”给出了

(define (first-not-second l1 l2)

  (define (first-not-second-helper l1 l2)
    (if (empty? l1)
        '()
        (let ((x (car l1)))
          (if (member x l2)
              (first-not-second-helper (cdr l1) l2)
              (cons x (first-not-second-helper (cdr l1) l2))))))

  (first-not-second-helper l1 l2))

在任何情况下,您都不需要遍历第二个列表,因为您可以使用内置member过程。

答案 1 :(得分:1)

该过程执行列表差异操作,将此视为设置差异很有用。诀窍是使用member来确定元素是否在列表中。我不会通过给出一个直接的答案来破坏你的乐趣,只需填写解决方案框架中的空白:

(define (diff l1 l2)
  (cond (<???>  ; if the 1st list is empty
         <???>) ; then we're done building the answer, return the empty list
        (<???>  ; if the 1st list's current element is not a member of 2nd list
         (cons <???>             ; then cons the 1st list's current element
               (diff <???> l2))) ; and advance the recursion
        (else                    ; otherwise
         (diff <???> l2))))      ; just advance the recursion

请注意,我们只遍历第一个列表,第二个列表在迭代中保持不变。