如何解决如何在球拍
所以我有这个程序,它有几个定义。这里感兴趣的三个是(集合等于L1 L2),(工会S1 S2)和(相交S1 S2)。
对于集等于?它应该测试L1和L2是否相等,如果两个集合包含完全相同的成员,则两个集合相等,而忽略顺序,因此如果调用以下内容: (set-equal?'(1(2 3))'((3 2)1)),则应返回true。但是,当我在上述调用中运行程序时,返回false。
两组的联合是出现在任一组中且没有重复的所有元素的集合。因此,当调用以下命令时: (联合'(((1 2 3))'((3 2 1)))),则应返回((1 2 3))。但是,当我运行程序时,上面的调用返回((1 2 3)(3 2 1)。
两组的相交是出现在两组中的元素的集合。因此,当调用以下命令时: (与'(((1 2 3))'((3 2 1)))相交,它应该返回((1 2 3))。但是,当我在上述调用中运行程序时,它将返回()。
我的其他一些测试用例确实可以按预期工作。但是,并非所有程序都正确。我真的是Racket的新手,觉得有点困惑。我不确定如何解决上述问题。我在想也许我需要另一个辅助函数,但是它将做什么?更重要的是,如何?
我的问题似乎是当集合包含其他集合时,这就是我不确定如何处理的问题。
代码在下面。
; Tests if x is in L where L is a set,represented as a list
(define (member? x L)
(if (null? L)
#f
(cond
[(eq? x (car L)) #t]
(else (member? x (cdr L))
))))
; Test whether L1 is a subset of L2
(define (subset? L1 L2)
(if (null? L1)
#t
(and (member? (car L1) L2)
(subset? (cdr L1) L2)
)))
; Test whether L1 and L2 are equal
(define (set-equal? L1 L2)
(and (subset? L1 L2)
(subset? L2 L1)
))
; Join two sets together
(define (union S1 S2)
(if (null? S1)
S2
(cond
[(member? (car S1)S2) (union (cdr S1)S2)]
(else (cons (car S1) (union (cdr S1)S2)))
)))
; Return the intersection of two sets
(define (intersect S1 S2)
(if (null? S1)
'()
(cond
[(member? (car S1)S2)
(cons (car S1) (intersect (cdr S1)S2))]
(else (intersect(cdr S1)S2))
)))
感谢您的帮助。谢谢
解决方法
您对set-equal?
的定义在两个方向上都使用subset?
,这很好。
您对subset?
的定义在元素和集合之间使用member?
,就可以了。
但是您对member?
的定义在元素之间使用了eq?
,即使这些元素可以设置(具有不同顺序的列表)也是如此。如果要使这些集合等效,则需要停止使用eq?
,并在嵌套数字集上定义一个新函数。
;; A NestedNumberSet is one of:
;; - Number
;; - [Listof NestedNumberSet]
;; where order doesn't matter in the lists
如果两个NestedNumberSet
都是数字且均为nested-number-set=?
,或者如果都是集合且均为=
,则根据set-equal?
相等。
;; nested-number-set=? : NestedNumberSet NestedNumberSet -> Boolean
(define (nested-number-set=? a b)
(cond [(and (number? a) (number? b)) (= a b)]
[(and (list? a) (list? b)) (set-equal? a b)]
[else #false]))
然后,如果将eq?
的使用替换为nested-number-set=?
的使用,则应该获得所需的嵌套集平等行为。
P.S。在您了解更多之前,我建议您不要再依赖代码中的eq?
。基本上,它只不过是指针相等,所以即使(eq? (list 1 2) (list 1 2))
也会返回#false
。
这样定义很容易。
(set-equal? '(1 (2 3)) '((2 3) 1))
返回#true
(set-equal? '(1 (2 3)) '((3 2) 1))
返回#false
#lang racket
(define s1 '(1 2 3 4 5 6))
(define s2 '(1 2 3 7 8 9))
(define (union S1 S2)
(remove-duplicates (append S2 S1)))
(union s2 s1) ; '(1 2 3 4 5 6 7 8 9)
(union '() '()) ; '()
(define (intersect S1 S2)
; just like (if '() #t #f) -> #t
(filter (lambda (e) (member e S2)) S1))
;;; TEST
(intersect s1 s2) ; '(1 2 3)
(intersect s1 '()) ; '()
在set-equal?
中,我们检查列表的length
是否相等。如果不相等,则显然不相同。
如果两个集合的长度相同,但是它们是不同的集合。在union
之前,我们可以确定更长的时间。
(define (set-equal? S1 S2)
(let ([c1 (length S1)]
[c2 (length S2)]
[c1^c2 (length (union S1 S2))])
(if (= c1 c2) (= c1 c1^c2) #f)))
;;; TEST
(set-equal? (union s1 s2) (union s2 s1)) ; #t
(set-equal? (union '() s1) s1) ; #t
(set-equal? '() '()) ; #t
(set-equal? '(1 (2 3)) '((2 3) 1)) ; #t
(set-equal? '(1 (1)) '((1) 1)) ; #t
(set-equal? '(1 (2 3)) '((3 2) 1)) ; #f
(set-equal? s1 s2) ; #f
(set-equal? '(1 2) '()) ; #f
您真的希望(set-equal? '(1 (2 3)) '((3 2) 1))
返回#ture
。并且(set-equal? '(1 (2 (3 4))) '(((3 4) 2) 1))
返回#ture
。在每一层都有效。祝你好运。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。