方案:从列表中删除重复的数字

时间:2011-12-05 07:42:40

标签: list scheme duplicate-removal

我编写了这段代码来创建一个列表来自 en 给出的参数数量

(define (create-list . e)
   e)

但是我需要它从这个块本身的列表中删除任何重复的数字。

我已经尝试并搜索了几个小时,如果没有在其他块上放置几十行代码就无法找到解决方案。

例如,假设我的输入是

(create-list . 2 2 3 5 5 )

我需要创建的列表为'(2 3 5)而不是'(2 2 3 5 5)......

数字的顺序无关紧要。

4 个答案:

答案 0 :(得分:4)

基本上,您需要执行以下操作:

(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)))))

答案 1 :(得分:2)

这个更快:

(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-scheme提供了删除重复,完全符合您的要求。

答案 2 :(得分:0)

最有效(遍历列表一次)的方法是定义一个逐个元素遍历列表的函数。该函数存储已包含在已删除列表中的元素的列表。

这个解决方案优于@Tikhon Jelvis的优点是,列表元素不需要按顺序进行重复数据删除。

给定一个函数elem,它表示al的元素:

(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)))))

注意:为了提高效率,它会以相反的顺序返回元素

答案 3 :(得分:0)

(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))))
)
)