Схема: удалить дублирующиеся номера из списка - PullRequest
5 голосов
/ 05 декабря 2011

Я написал этот код, чтобы создать список из en числа аргументов

(define (create-list . e)
   e)

Но мне нужно, чтобы удалить все дублирующиеся номера из списка внутри этого блока.

Я искал несколько часов и не могу найти решение, не поместив десятки строк кода в другие блоки.

Например, скажем, мой ввод

(create-list . 2 2 3 5 5 )

Мне нужен список, созданный для '(2 3 5), а не' (2 2 3 5 5) ...

Порядок чисел не имеет значения.

Ответы [ 4 ]

4 голосов
/ 05 декабря 2011

По сути, вам нужно сделать что-то вроде:

(define (create-list . e) (dedupe e))

Я могу придумать действительно простой, но, вероятно, неэффективный способ сделать это:

(define (dedupe e)
  (if (null? e) '()
      (cons (car e) (dedupe (filter (lambda (x) (not (equal? x (car e)))) 
                                    (cdr e))))))

Если вы не можетеиспользуйте существующие функции, такие как filter, вы можете сделать их самостоятельно:

(define (my-filter pred ls) 
  (cond ((null? ls) '())
        ((pred (car ls)) (cons (car ls) (my-filter pred (cdr ls))))
        (else (my-filter pred (cdr ls)))))
2 голосов
/ 26 апреля 2012

Это быстрее:

(define (remove-duplicates l)
  (cond ((null? l)
         '())
        ((member (car l) (cdr l))
         (remove-duplicates (cdr l)))
        (else
         (cons (car l) (remove-duplicates (cdr l))))))

Но даже лучше, mit-схема обеспечивает удаление дубликатов, что делает именно то, что вы хотите.

0 голосов
/ 14 марта 2014
(define (delete x)
(cond
((null? x) x)
((= (length x) 1) x) | ((null? (cdr x)) x)
((= (car x) (cadr x)) (delete (cdr x)))
(#t (cons (car x) (delete (cdr x))))
)
)
0 голосов
/ 06 декабря 2011

Наиболее эффективный (обход списка один раз) способ сделать это состоит в том, чтобы определить функцию, которая проходит по списку элемент за элементом. Функция хранит список элементов, которые уже находятся в дублированном списке.

Преимущество этого решения перед @Tikhon Jelvis в том, что элементы списка не должны быть в порядке, чтобы быть дедуплицированными.

Дана функция elem, которая сообщает, является ли a элементом l:

(define (elem? a l)
      (cond ((null? l) #f)
            ((equal? a (car l)) #t)
            (else (elem? a (cdr l)))))

Мы можем просмотреть список, сохранив каждый элемент, который мы не видели раньше:

(define (de_dupe l_remaining already_contains)
   (cond ((null? l_remaining) already_contains)
         ((elem? (car l_remaining) already_contains) (de_dupe (cdr l_remaining) already_contains))
         (else (de_dupe (cdr l_remaining) (cons (car l_remaining) already_contains)))))

Примечание: для эффективности это возвращает элементы в обратном порядке

...