How to get rid of duplicates in a list, but keep the order

泪湿孤枕 提交于 2019-12-21 04:44:08

问题


I am using Intermediate Student with Lambda in DrRacket, I was wondering how one would remove the duplicates in a list, while keeping the order. For example (remove-dup (list 2 5 4 5 1 2)) would produce (list 2 5 4 1). So far, I have this:

(define (remove-duplicates lst)
  (cond
    [(empty? lst) empty]
    [(member? (first lst) (rest lst)) 
     (remove-duplicates (rest lst))]
    [else (cons (first lst) (remove-duplicates (rest lst)))]))

, but there's a problem since it doesn't keep the order. Can someone point me in the right direction? Thanks for your time.


回答1:


If your goal is to get the functionality working, and not some homework question, then you don't need to do anything, just use remove-duplicates:

Welcome to Racket v5.2.
-> (remove-duplicates (list 2 5 4 5 1 2))
'(2 5 4 1)



回答2:


This is the solution:

(define (remove-duplicates lon)
  (foldr (lambda (x y) (cons x (filter (lambda (z) (not (= x z))) y))) empty lon))



回答3:


SRFI-1 has delete-duplicates, although it's inefficient. (I am not too familiar with Racket, but surely it has SRFI-1, and the source...)

http://srfi.schemers.org/srfi-1/srfi-1.html#delete-duplicates




回答4:


Run through the list sequentially, inserting each element in a hash table or other dictionary. If you try to insert an element that is already in the hash table, do not add it to the outgoing list.




回答5:


What you need to do is compare in reverse order the entire time. You can use the reverse function which returns a list in reverse order. That way you are always removing the 2nd+ occurrence of an element and not the first. Here is an example, however it is using let and if and not a cond expression.

http://www.cs.bgu.ac.il/~elhadad/scheme/duplicates.html

Good luck with your homework :)




回答6:


hmm i just had a racket exam recently, :/

the 'standard' remove-duplicates works fine but i was using pretty-big in drRacket so it had to be loaded using (require racket/list)

here is an alternative way :)

using mutation (not really in the spirit of racket but.. it works.)

    (define (set l)
        (define the-set '())
            (begin (for-each
                       (lambda (x)
                            (if (member x the-set)
                                #t
                            (set! the-set (cons x the-set))))
                       l)
                   (reverse the-set)))

hope this helps... cheers!




回答7:


Old question, but this is an implementation of J-Y's idea.

(define (dup-rem lst)
  (cond
    [(empty? lst) empty]
    [else (cons (first lst) (dup-rem (filter (lambda (x) (not (equal? (first lst) x))) lst)))]))



回答8:


I'm not sure if this is homework, but in case it is I'll post just the idea. If it's not tell me and I can put a solution here.

What you need is to keep track of the unique items you find, you can do that by using an auxiliary list, like an accumulator, to keep track of the ones you found so far.

Whenever you look at another item check to see if it's in the auxiliary list. In case it's not add it to the auxiliary list.

You'll end up with a reverse order of what you're trying to find, so you can just (reverse ...) it and you'll have your answer.



来源:https://stackoverflow.com/questions/8146160/how-to-get-rid-of-duplicates-in-a-list-but-keep-the-order

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