如何从可能包含Racket中列表的列表中删除重复项

时间:2018-12-12 22:36:10

标签: list scheme racket

我编写的代码:

 (define (make-list lst)
  (cond [(null? lst) '()]
        [(member (car lst) (cdr lst)) (make-list (cdr L))]
        [else (cons (car lst) (duplicates (cdr lst)))]))

我希望(make-list '(a (a b b (c b) 3) 5 5.0 (e s) (s e s)))))返回:

(a (a b (c b) 3) 5 (e s))

但是我的程序返回了

'((a b b (c b) 3) 5 5.0 (e s) (s e s))

因此,除了删除第一个元素外,它实际上没有做任何事情,它也不会进入嵌套列表。任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

我假设duplicatesL被忘记了重命名错误。 make-list并不是一个好名字,因为它是R7RS列表库中的一个众所周知的过程,该过程最初来自SRFI-1列表库。 remove-duplicates可能更合适?

(define (remove-duplicates lst)
  (cond [(null? lst) '()]
        [(member (car lst) (cdr lst))
         (remove-duplicates (cdr lst))]
        [else
         (cons (car lst) (remove-duplicates (cdr lst)))]))

现在,这将处理给定列表中的所有元素,并且仅与顶级列表有关。子列表也被比较:

(remove-duplicates '(a (b c) (b c) a))
; ==> ((b c) a)

您不仅需要使用第一个元素创建列表,还需要检查第一个元素是否为列表,并在这两部分上进行remove-duplicates。因此,您需要添加这样的术语:

(define (remove-duplicates lst)
  (cond [(null? lst) '()]
        [(member (car lst) (cdr lst))
         (remove-duplicates (cdr lst))]
        [(list? (car lst)) ; or pair?
         (cons (remove-duplicates (car lst)) 
               (remove-duplicates (cdr lst)))]         
        [else
         (cons (car lst)
               (remove-duplicates (cdr lst)))]))

(remove-duplicates '((a b b a) (a b b a)))
; ==> ((b a))