Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 方案:从列表中删除重复的数字_List_Scheme_Duplicate Removal - Fatal编程技术网

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

List 方案:从列表中删除重复的数字,list,scheme,duplicate-removal,List,Scheme,Duplicate Removal,我编写这段代码是为了根据给定的参数数量创建一个列表 (define (create-list . e) e) 但是我需要它来从这个块本身的列表中删除任何重复的数字 我已经尝试和搜索了几个小时,如果不在其他块上放置几十行代码,就找不到解决方案 例如,假设我的输入是 (create-list . 2 2 3 5 5 ) 我需要创建的列表是'(2 3 5)而不是'(2 3 5 5) 数字的顺序无关紧要。基本上,你需要做一些事情,比如: (define (create-list . e) (d

我编写这段代码是为了根据给定的参数数量创建一个列表

(define (create-list . e)
   e)
但是我需要它来从这个块本身的列表中删除任何重复的数字

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

例如,假设我的输入是

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


数字的顺序无关紧要。

基本上,你需要做一些事情,比如:

(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))))))
如果您不能使用现有的功能,如
过滤器
,您可以自己制作一个:

(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)))))
实现这一点的最有效方法(遍历列表一次)是定义一个逐个元素遍历列表元素的函数。该函数存储已在重复数据消除列表中的元素的列表

与@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)))))
注意:为了提高效率,这将以相反的顺序返回元素

这一个更快:

(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提供删除重复项,这正是您想要的。

是否可以仅使用cdr/car/cons和原始过程创建相同的代码?(无过滤器/头部/尾部)是。事实上,
head
tail
已经分别是
car
cdr
(我脑子里有太多的Haskell)。另外,请注意我的语法可能有点不对劲——我最近才用了很多Haskell,我只用过stk,它是一个过时的方案解释器。对不起,我不习惯它。刚刚检查了编辑后的答案。非常感谢。通常,
filter
接受一个列表和一个谓词(返回true或false的函数),并返回一个仅包含谓词返回true的元素的列表。您可以将其视为一个
选择位置
。我的版本是否需要任何顺序的元素?就我所知,它不是。@Tikhon-Jelvis:它看起来像它;不过,我无法让它返回正确的值。例如:“(createlist354346)”返回“(333)”,这不是因为顺序,而是因为我不小心在过滤器的谓词中漏掉了not。我现在修好了。另请参见
(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))))
)
)