Как удалить дубликаты из списка, который может содержать списки в Racket - PullRequest
0 голосов
/ 13 декабря 2018

Код, который я написал:

 (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 голосов
/ 13 декабря 2018

Я предполагаю, что duplicates и L забыли ошибки переименования.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))
...