0

嗨,我想编写一个简单的函数,它采用 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) 

谢谢

4

2 回答 2

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)

球拍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过程。

于 2013-10-25T20:42:12.667 回答
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

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

于 2013-10-25T20:46:59.907 回答