1

我是新来的计划和做一些练习。我正在尝试执行以下操作:我要编写的函数采用一个列表参数(不需要输入检查)。然后它删除元素的多次出现并返回新列表。这是一个输入输出示例:让我们调用函数“一次”,

=>(once '(1 2 5 2 3 4 2 4 1 2))
=>Value: (1 2 5 3 4)

这是我的解决方案:

(define once
  (lambda (lst)
    (if (null? lst) 
        '() 
        (if (member (car lst) (cdr lst)) 
            (once (cdr lst)) 
            (cons (car lst) (once (cdr lst)))))))

但是元素的顺序发生了变化,尽管它消除了重复。任何人都可以帮忙吗?谢谢

4

4 回答 4

2
(define once L
 (if (null? L)
  '()
   (cons (car L) (once (filter (n-eq-x? (car L)) (cdr L))))))

(define (n-eq-x? value)
 (lambda (x) (if (eq? value x) #f #t)))

你可以用助手编写它

(define (once L)
 (reverse (once-helper L '())))

(define (once-helper L L-once)
 (cond ((null? L) L-once)
       ((member? (car L) (L-once) 
        (once-helper (cdr L) L-once))
       (else (once-helper (cdr L) (cons (car L) L-once)))))

更接近原始的,这里的区别在于,不是用未出现在列表的其余部分中的元素构建一个列表,而是构建第二个列表,其中原始的元素还不是成员。如果您已经拥有该元素,则该检查将变为假,如果您稍后要获取该元素,则该检查将变为假。

于 2013-05-03T22:42:45.590 回答
1

在 Racket 中,就这么简单:

(define once remove-duplicates)
(once '(1 2 5 2 3 4 2 4 1 2))
=> '(1 2 5 3 4)

但是如果你必须从头开始实现它,这里是一般的想法,填空:

(define (once lst)
  (cond (<???>  ; is the list empty?
         <???>) ; return the empty list
        (<???>  ; is the current element member of the rest of the list?
         <???>) ; advance recursion
        (else   ; otherwise it's not duplicate,
         (cons <???>     ; cons current element
               <???>)))) ; advance recursion
于 2013-05-03T22:02:32.990 回答
1

在处理输入列表时,列表的头部有一个元素,列表的尾部有一个元素。

  1. 如果列表头部的元素在尾部,则不需要将其添加到结果中,因为它将在以后的迭代中被捕获。
  2. 如果列表头部的元素不在尾部,则将其推送到结果上。
  3. 递归。
于 2013-05-03T22:09:31.637 回答
1

lst如果项目不在结果中,您想要添加项目。

(define (once lst)
  (let looking ((lst lst) (rst '()))
    (if (null? lst)
        (reverse rst)                   ; leave order unchanged
        (let ((nxt (car lst)))
          (looking (cdr lst)
                   (if (member nxt rst) ; nxt in rst
                       rst              ; yes: don't augment rst
                       (cons nxt rst)))))))
于 2013-05-03T23:49:48.053 回答