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

后端 未结 2 2022
礼貌的吻别
礼貌的吻别 2020-12-20 05:10

I know how to write this in an recursive way.

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


        
相关标签:
2条回答
  • 2020-12-20 05:50

    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.

    0 讨论(0)
  • 2020-12-20 06:06

    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)))
    
    0 讨论(0)
提交回复
热议问题