如何在方案中编写以下函数

时间:2013-05-03 22:00:30

标签: functional-programming scheme

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

=>(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 个答案:

答案 0 :(得分: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)))))

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

答案 1 :(得分: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

答案 2 :(得分:1)

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

  1. 如果列表顶部的元素位于尾部,那么您不需要将其添加到结果中,因为它将在稍后的迭代中捕获。
  2. 如果列表顶部的元素不在尾部,请将其推送到结果上。
  3. 递归。

答案 3 :(得分: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)))))))