【问题标题】:How to find sets containing sets in Racket如何在 Racket 中查找包含集合的集合
【发布时间】:2020-10-17 02:37:34
【问题描述】:

所以我有这个程序有几个定义。这里感兴趣的三个是 (set-equal? L1 L2)、(union S1 S2) 和 (intersect S1 S2)。

设置相等?它应该测试 L1 和 L2 是否相等,如果两个集合包含完全相同的成员,则它们相等,忽略排序,因此如果调用以下命令: (set-equal? '(1 (2 3)) '((3 2) 1)),它应该返回 true。但是,当我在上述调用上运行我的程序时,返回 false。

两个集合的并集是出现在任一集合中且没有重复的所有元素的集合。因此,当调用以下内容时: (union '((1 2 3)) '((3 2 1))),它应该返回 ((1 2 3))。但是,当我运行我的程序时,上面的调用返回 ((1 2 3) (3 2 1)。

两个集合的交集是出现在两个集合中的元素集合。因此,当调用以下内容时: (intersect '((1 2 3)) '((3 2 1))),它应该返回 ((1 2 3))。但是,当我在上面的调用中运行我的程序时,它会返回 ()。

我的其他一些测试用例确实按预期工作。然而,并不是所有的,因此,该程序并不完全正确。我对球拍真的很陌生,发现它有点混乱。我不太确定如何解决提到的问题。我在想也许我需要另一个辅助函数,但它会做什么?更重要的是,如何?

我的问题似乎是当集合包含其他集合时,我不确定该如何处理。

代码如下。

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

感谢您的所有帮助。谢谢

【问题讨论】:

  • 不要破坏你的问题;堆栈溢出的重点是帮助未来有同样问题的读者,而不仅仅是你。 (如果您出于某种法律原因需要从问题中删除某些内容,例如您发布了没有版权许可的代码,请在您的问题上举旗联系版主。)
  • 以下答案参考原代码;当您删除该代码时,答案对于没有看到原始代码的未来读者来说意义不大。不要以使现有答案无效的方式编辑您的答案。回滚。
  • @exnihilo 我认为这甚至是关于 SO 的官方规则:“编辑不得使现有答案无效”。 :)

标签: list set subset racket sublist


【解决方案1】:

您对set-equal? 的定义在两个方向上都使用subset?,这很好。 您对subset? 的定义在元素和集合之间使用了member?,这很好。

但是您对member? 的定义在元素之间使用eq?,即使这些元素可以是集合(具有不同排序的列表)。如果您希望这些集合等效,则需要停止使用eq?,并在嵌套的数字集合上定义一个新函数。

;; A NestedNumberSet is one of:
;;  - Number
;;  - [Listof NestedNumberSet]
;; where order doesn't matter in the lists

如果两个NestedNumberSets 都是数字并且它们是=,或者如果它们都是集合并且它们是set-equal?,则两个NestedNumberSets 相等。

;; 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=? 的使用,您应该会获得所需的嵌套设置相等行为。


附:在您了解更多信息之前,我建议您停止在代码中依赖 eq?。基本上无非就是指针相等,所以即使(eq? (list 1 2) (list 1 2)) 也会返回#false

【讨论】:

    【解决方案2】:

    这样定义很容易。

    (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。在每一层工作。祝你好运。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      相关资源
      最近更新 更多