List order after duplicate filtering

我怕爱的太早我们不能终老 提交于 2019-12-20 03:15:04

问题


I'm trying to teach myself functional language thinking and have written a procedure that takes a list and returns a list with duplicates filtered out. This works, but the output list is sorted in the order in which the last instance of each duplicate item is found in the input list.

(define (inlist L n)
  (cond
   ((null? L) #f)
   ((= (car L) n) #t)
   (else (inlist (cdr L) n))
   ))

(define (uniquelist L)
 (cond
   ((null? L) '())
   ((= 1 (length L)) L)
   ((inlist (cdr L) (car L)) (uniquelist (cdr L)))
   (else (cons (car L) (uniquelist (cdr L))))
   ))

So..

(uniquelist '(1 1 2 3)) => (1 2 3)

...but...

(uniquelist '(1 2 3 1)) => (2 3 1)

Is there a simple alternative that maintains the order of the first instance of each duplicate?


回答1:


The best way to solve this problem would be to use Racket's built-in remove-duplicates procedure. But of course, you want to implement the solution from scratch. Here's a way using idiomatic Racket, and notice that we can use member (another built-in function) in place of inlist:

(define (uniquelist L)
  (let loop ([lst (reverse L)] [acc empty])
    (cond [(empty? lst)
           acc]
          [(member (first lst) (rest lst))
           (loop (rest lst) acc)]
          [else
           (loop (rest lst) (cons (first lst) acc))])))

Or we can write the same procedure using standard Scheme, as shown in SICP:

(define (uniquelist L)
  (let loop ((lst (reverse L)) (acc '()))
    (cond ((null? lst)
           acc)
          ((member (car lst) (cdr lst))
           (loop (cdr lst) acc))
          (else
           (loop (cdr lst) (cons (car lst) acc))))))

The above makes use of a named let for iteration, and shows how to write a tail-recursive implementation. It works as expected:

(uniquelist '(1 1 2 3))
=> '(1 2 3)

(uniquelist '(1 2 3 1))
=> '(1 2 3)


来源:https://stackoverflow.com/questions/22001929/list-order-after-duplicate-filtering

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