Lisp 有没有办法将列表转换为集合方案?

Lisp 有没有办法将列表转换为集合方案?,lisp,scheme,Lisp,Scheme,我想测试列表之间是否相等,但我真正关心的是成员是否相同,而不是顺序。有没有简单的操作员来检查这一点 一个相当微不足道的例子 (my-equal? (a b) (b a)) 应该返回#t 显然,通过检查两个列表,然后反转第二个列表并再次检查,可以很容易地完成这个特定示例 (or (equal? (a b) (b a)) (equal? (a b) (reverse (b a))) 但总的来说有办法吗?我可以尝试写一个函数,但我只能想象一些相当复杂的东西来完成这项工作。我猜这一定是一个相当普遍的

我想测试列表之间是否相等,但我真正关心的是成员是否相同,而不是顺序。有没有简单的操作员来检查这一点

一个相当微不足道的例子

(my-equal? (a b) (b a))
应该返回#t

显然,通过检查两个列表,然后反转第二个列表并再次检查,可以很容易地完成这个特定示例

(or (equal? (a b) (b a)) (equal? (a b) (reverse (b a)))
但总的来说有办法吗?我可以尝试写一个函数,但我只能想象一些相当复杂的东西来完成这项工作。我猜这一定是一个相当普遍的需求,我想知道这个方案是否内置了一个操作员,可以在这里完成这项工作


我正在使用mit scheme 9.0.1

如果您的实现可用,那么有
lset=
来实现您想要的:


如果您使用的是Racket,我会告诉您,它内置了对set的支持


不,我知道,这并没有回答你的问题。

或者如果你想老生常谈,你可以只写几个小函数

我真诚地希望你不要用这个做家庭作业

(define (unordered-union-set set1 set2)
    (cond ((null? set2) set1)
        (else 
            (if (in-set? (car set2) set1)
                (unordered-union-set set1 (cdr set2)) 
                (cons (car set2) (unordered-union-set (cdr set2) set1))))))

(define (in-set? item set)
    (cond ((null? set) #f)
        ((equal? item (car set)) #t)
        (else (in-set? item (cdr set)))))

(define (set-equal? set1 set2)
    (if (equal? (length set1) (length set2))
        (if (equal? (length set1) (length (unordered-union-set set1 set2)))
            #t
            #f)
    #f))
使用set equal?在任意两组上

这是基于一些简单的集合理论。如果两个等价基数集的并集产生一个基数与第一个或最后一个集合的基数相等的集合,则这些集合是等价的

我写这篇文章的目的是说没有简单的操作符,但是如果你使用集合并集技巧的话,一个长而复杂的过程是不必要的

我的实现没有SRFI 1,但我非常怀疑lset=是否会比这个函数快


但现在我已经阅读了您的评论,您需要它对'(12)和'(21)有效。因为这些不是集合,所以此方法不起作用,但不难实现。所以,实际上,这个过程相当于lset=。

请记住,在Scheme中。。。已写入列表数据结构(列表7 8)或(cons 9(cons null))。也许你应该写一个散列映射到实现集。一个不明确的问题是你是否会考虑列表(比如1(1)2)和“2”(1)。换句话说,重复项有什么意义吗?@john如果它是一个基本集合,那么不应该计算重复项。请注意,这并不是“将列表转换为集合”——它只是将列表视为集合。(这对某些有限的情况很有用。)非常好。谢谢这正是我想要的。