How to remove all the duplicates in a list using scheme (only abstract list functions allowed)

你说的曾经没有我的故事 提交于 2020-01-10 04:36:05

问题


I know how to write this in an recursive way.

(define (removed2 lst)
  (cond
       [(empty? lst) empty]
       [(not (member? (first lst) (rest lst)))
        (cons (first lst) (removed2 (rest lst)))]
       [else (removed2 (rest lst))]))

so (removed2 (list 1 1 1 2 2 2 3 3 3 3 3 3)) gives (list 1 2 3)

However, how do you rewrite it only using abstract functions (filter, foldr, map, and build-list)?

I tried to use filter but it just doesn't work.


回答1:


It's possible to use foldr for this, the trick is knowing what to write in the lambda:

(define (removed lst)
  (foldr (lambda (e a)
           (if (not (member? e a))
               (cons e a)
               a))
         '()
         lst))

Also check if your interpreter has a built-in function, for instance in Racket you can use remove-duplicates.




回答2:


FILTER

Just for kicks, a version with filter:

(define (make-unique-filter)
  (let ((seen '()))
    (lambda (e)
      (if (member e seen)
          #f
          (begin
            (set! seen (cons e seen))
            #t)))))

(define (removed2 lst)
  (filter (make-unique-filter) lst))

then

(removed2 (list 1 1 1 2 2 2 3 3 3 3 3 3))
=> '(1 2 3)
(removed2 (list 1 2 3 1 2 3 1 2 3 1 2 3))
=> '(1 2 3)

FOLD

But of course, fold is the way to go. However, it is generally preferable to user a left fold (at least in Racket, see here), but the result has to be reversed:

(define (removed2 lst)
  (reverse 
   (foldl 
    (lambda (e a)
      (if (not (member e a))
          (cons e a)
          a))
    '()
    lst)))

or in pure Scheme:

(define (removed2 lst)
  (reverse 
   (fold-left 
    (lambda (a e)
      (if (not (member e a))
          (cons e a)
          a))
    '()
    lst)))


来源:https://stackoverflow.com/questions/21298989/how-to-remove-all-the-duplicates-in-a-list-using-scheme-only-abstract-list-func

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!