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