问题
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