List 计划单词表?

List 计划单词表?,list,scheme,equals,List,Scheme,Equals,我有一个问题:我需要找出列表是否等于第二个,例如: (set%eq? '(1 2 3) '(1 2 3)) ===> #t (set%eq? '(1 2 3) '(2 3 4)) ===> #f 我的程序中的示例是正确的,但这一个不是: (set%eq? (quote ((quote one) (quote two) (quote three))) (quote ((quote one) (quote two) (quote three)))) ====&

我有一个问题:我需要找出列表是否等于第二个,例如:

(set%eq? '(1 2 3) '(1 2 3))     ===> #t

(set%eq? '(1 2 3) '(2 3 4))     ===> #f
我的程序中的示例是正确的,但这一个不是:

(set%eq? (quote ((quote one) (quote two) (quote three))) (quote ((quote one) (quote two) 
(quote three))))    ====> #f but i need #t
怎么了? 这是我的节目:

(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)))

发布的代码中有几个错误,仅供参考,该过程测试两个列表是否相等,但实际上并不是测试两个集合之间是否相等:

现在这将起作用:

(set-eq? '(1 2 3) '(1 2 3))
=> #t

(set-eq? '(1 2 3) '(2 3 4))
=> #f

(set-eq? (quote ((quote one) (quote two) (quote three)))
         (quote ((quote one) (quote two) (quote three))))
=> #t
事实上,这也会起作用:

(equal? '(1 2 3) '(1 2 3))
=> #t

(equal? '(1 2 3) '(2 3 4))
=> #f

(equal? (quote ((quote one) (quote two) (quote three)))
        (quote ((quote one) (quote two) (quote three))))
=> #t
…但这行不通,列表显然不同:

(set-eq? '(1 2 3 4) '(4 1 2 3)) 
=> #f

如果您打算测试两个集合之间的相等性,则必须完全重新考虑算法。这里有一个想法:编写一个
子集?
过程,测试一个列表是否是另一个列表的子集(即:如果一个列表中的所有元素都包含在另一个列表中),然后测试
(和(子集?l1 l2)(子集?l2 l1))
是否为真,如果出现这种情况,然后根据相等的集合定义,它们相等。

根据OP的评论,很明显它们是
set eq?

(set-eq? '(a b c) '(c b a)) ; ==> #t
(set-eq? '(a b c) '(b c a)) ; ==> #t
(set-eq? '() '())           ; ==> #t
(set-eq? '(a b) '(a b c))   ; ==> #f
(set-eq? '(a b c) '(a c))   ; ==> #f
如果列表没有重复项,可以迭代第一个列表并尝试在第二个列表中找到它。如果找到,我们将使用两个不匹配的列表进行递归

#!r6rs
(import (rnrs)
        (rnrs lists))

(define (set-eq? xs ys)
  (if (null? xs) 
      (null? ys) ; #t if both sets are empty, otherwise #f
      (let ((cur (car xs)))        
        (and (memq cur ys) ; first element is found 
             (set-eq? <??> (remq <??> <??>)))))) ; recurse without first in both lists
#!r6rs
(进口(rnrs)
(rnrs列表)
(定义(设置等式?x和y)
(如果(空?xs)
(null?ys)#t如果两个集合都为空,则为#f
(让((cur(car xs)))
(和(memq cur ys);找到第一个元素
(设置eq?(remq()())));在两个列表中递归而不使用第一个

有很多方法可以加快速度。E.q.对第一个列表进行散列,然后迭代第二个列表。如果所有匹配项和
哈希表大小
与迭代次数相同,则为#t

您是否尝试过使用
equal?
什么应该
(设置%eq?'(1 2 3)'(1 3 2))
返回。。。显然,你现在离线了。问而不留下来澄清,真是不礼貌|它应该返回#t,但即使现在也不知道该怎么做..从名称上看,OP可能是在追求集合相等。因此,试图以相反的方式进行比较。。。不幸的是,它们是离线的|@但问题OP中的“我需要找出列表是否等于第二个”。很难说,无论如何,颠倒列表是行不通的…(定义(seteq?xs-ys)(cond((and(null?xs)(null?ys))#t((or(null?xs)(null?ys))#f);缺少case((equal)(car xs)(car ys))(seteq?(cdr xs)(cdr ys));使用equal?;删除不必要的case(else#f)))“这确实有效,但还有一个问题,它不适用于像(set eq?)(1234),(4123))===>#f这样的数字,但我需要#不应该用它做什么?@dengar如果这是因为你写的是测试列表之间相等性的算法,它对集合不起作用(在每一步颠倒列表对你没有任何好处)。这是一个完全不同的问题,一个想法是:编写一个过程来测试一个列表是否是另一个列表的子集(即:一个列表中的所有元素是否都包含在另一个列表中),然后测试
(和(子集?l1 l2)(子集l2 l1))
是否为真
#!r6rs
(import (rnrs)
        (rnrs lists))

(define (set-eq? xs ys)
  (if (null? xs) 
      (null? ys) ; #t if both sets are empty, otherwise #f
      (let ((cur (car xs)))        
        (and (memq cur ys) ; first element is found 
             (set-eq? <??> (remq <??> <??>)))))) ; recurse without first in both lists