i've got a problem: I need to find if list equal to the second one, for example:
(set%eq? '(1 2 3) '(1 2 3)) ===> #t
(set%eq? '(1 2 3) '(2 3 4)) ===> #f
That examples are correct in my program, but this one is not:
(set%eq? (quote ((quote one) (quote two) (quote three))) (quote ((quote one) (quote two)
(quote three)))) ====> #f but i need #t
what's wrong? this is my program:
(define (set-eq? xs ys)
(cond ((and (null? xs) (null? ys)) #t)
((null? ys) #f)
((eq? (car xs) (car ys)) (set-eq? (cdr xs) (cdr ys)))
((eq? (car xs) (car (reverse ys))) (set-eq? (cdr xs) (cdr (reverse ys))))
(else #f)))
There are a couple of mistakes in the posted code, and FYI, the procedure tests whether two lists are equal, it's not really testing for equality between two sets:
Now this will work:
In fact, this will work, too:
...But this won't work, the lists are clearly different:
If you intended to test for equality between two sets, you have to completely rethink the algorithm. Here's an idea: write a
subset?
procedure that tests if a list is a subset of another list (that is: if all the elements in one list are contained in the other list), and then test whether(and (subset? l1 l2) (subset? l2 l1))
is true, if that happens, then they're equal according to the set definition of equality.Base on the comments from OP it's clear that these are
set-eq?
If the lists are without duplicates one could iterate the first list and try to find it in the second. If found we recurse with the two lists without the match.
There are ways to get this faster. E.q. Hash the first list and iterate the second. If all matches and
hashtable-size
is the same as the number of iterations it's #t.