如何在Scheme中附加另一个元素的当前列表?

时间:2011-04-21 00:42:49

标签: scheme

假设我有一个清单: a b a a a c e。 我想摆脱所有相邻的副本,即中间的两个副本。所以列表变成了 a b a c e

我目前想到的算法是,
- 通过

检查当前值是否等于下一个值
(equal? (car lst) (car (cdr lst)))

如果它们相等,那么我想跳过重复的元素,但我不知道如何在Scheme中实现这种行为?有什么想法?
- 如果它们不相等,请继续浏览列表。

顺便说一句,有没有办法在Scheme中为这些类型的问题实现迭代for循环?因为我觉得递归对于这个简单的问题来说太过分了。

谢谢,

3 个答案:

答案 0 :(得分:2)

我很长时间没有写过Scheme,但也许这会对你有所帮助:

(define (remove-adjacent-duplicates list)
    (if (empty? list)                    
        '()                              
        (if (equal? (car list) (cadr list))
            (remove-adjacent-duplicates (cdr list))
            (cons (car list) (remove-adjacent-duplicates (cdr list)))))

哦,不要害怕递归,特别是在Scheme中。好有趣! :)

答案 1 :(得分:1)

以下是使用fold解决此问题的迭代答案:

(define (uniq lst)
  (fold (lambda (elem result)
          (if (and (pair? result) (equal? elem (car result)))
              result
              (cons elem result)))
        '() (reverse lst)))

(将来,只要您尝试将列表转换为某些内容,请考虑使用fold,并且每当您尝试将某些内容转换为列表时,请考虑使用unfold。它们功能非常强大!)

答案 2 :(得分:0)

在这种情况下,您可能希望将cdr的汽车保存到递归调用的结果中(抛弃汽车,它会使用类似3 a的情况更容易检查)。现在你问的问题是什么是递归调用。那么,现在你把cdr的车放到了cdr上的recurion上。