【问题标题】:How to do a powerset in DrRacket?如何在 DrRacket 中进行 powerset?
【发布时间】:2014-01-04 13:17:07
【问题描述】:

我正在使用带有 DrRacket 列表缩写的开头语言,并且想递归地创建一个 powerset,但不知道如何去做。我现在有这么多

(define
  (powerset aL)
  (cond
    [(empty? aL) (list)]

任何帮助都会很好。

【问题讨论】:

标签: scheme racket powerset htdp


【解决方案1】:
 powerset 中有什么?一个集合的子集!
            空集是 any 集的子集,
            所以 empty 集的 powerset 的 not 为空。
            它的(唯一)元素是一个空集:
(define
  (powerset aL)
  (cond
    [(empty? aL) (list empty)]
    [else
 对于非空集合,有一个选择,
            对于每个集合的元素,是否是
            或不包含在子集中
            它是powerset的成员。 
因此,我们在组合时包含
both 选项 第一个具有较小幂集的元素, 那,我们递归地应用 其余输入的过程相同:
       (combine (first aL)
                (powerset (rest aL)))]))

(define
  (combine a r)                      ; `r` for Recursive Result
  (cond
    [(empty? r)  empty]              ; nothing to combine `a` with
    [else
      (cons (cons a (first r))       ; Both add `a` and
          (cons (first r)            ;   don't add, to first subset in `r`
              (combine               ; and do the same
                    a                ;   with 
                    (rest r))))]))   ;   the rest of `r`
 “没有答案,只有选择”。 相反,
            做出的选择,就是答案的组成。

【讨论】:

    【解决方案2】:

    这是另一个实现,经过几次测试后,它似乎比 Chris 对更大列表的回答要快。它使用标准球拍进行了测试:

    (define (powerset aL)
      (if (empty? aL)
          '(())
          (let ((rst (powerset (rest aL))))
            (append (map (lambda (x) (cons (first aL) x))
                         rst)
                    rst))))
    

    【讨论】:

    • 是的,那是我编写的原始实现(因为它比我最终发布的版本更简单,因此直观地浮现在脑海中),但我不喜欢结果的顺序元素。 (我知道,从什么时候开始订购,对吗?)仍然,有一个+1。 :-)
    【解决方案3】:

    在球拍中,

    #lang racket
    
    (define (power-set xs)
      (cond
        [(empty? xs) (list empty)]                 ; the empty set has only empty as subset
        [(cons? xs)  (define x  (first xs))        ; a constructed list has a first element
                     (define ys (rest  xs))        ; and a list of the remaining elements
                     ;; There are two types of subsets of xs, thouse that
                     ;; contain x and those without x.
                     (define with-out-x            ; the power sets without x
                       (power-set ys))                 
                     (define with-x                ; to get the power sets with x we 
                       (cons-all x with-out-x))    ; we add x to the power sets without x
                     (append with-out-x with-x)])) ; Now both kind of subsets are returned.
    
    (define (cons-all x xss)
      ; xss is a list of lists
      ; cons x onto all the lists in xss
      (cond
        [(empty? xss) empty]
        [(cons?  xss) (cons (cons     x (first xss))    ; cons x to the first sublist
                            (cons-all x (rest xss)))])) ; and to the rest of the sublists
    

    测试:

    (power-set '(a b c))
    

    【讨论】:

      【解决方案4】:

      这是我的 power set 实现(尽管我只使用标准 Racket 语言测试它,而不是初级学生):

      (define (powerset lst)
        (if (null? lst)
            '(())
            (append-map (lambda (x)
                          (list x (cons (car lst) x)))
                        (powerset (cdr lst)))))
      

      (感谢samth 提醒我,在 Racket 中平面地图被称为 append-map!)

      【讨论】:

      • 我喜欢这个解决方案,它比我发布的那个更简单,并且是一个很好的例子,展示了append-map 的用法。我想知道,为什么它变慢了?
      【解决方案5】:

      你可以只使用副作用:

      (define res '())
      
      (define
        (pow raw leaf)
        (cond
          [(empty? raw) (set! res (cons leaf res))
                        res]
          [else (pow (cdr raw) leaf)
                (pow (cdr raw) (cons (car raw) leaf))]))
      
      (pow '(1 2 3) '())
      

      【讨论】:

      • 不过,docs.racket-lang.org/htdp-langs/… 中没有 set!。但是很好很简单recursive-backtracking,这个。
      • 它可以在 DrRacket 上运行。
      • 问题是“我正在使用带有列表缩写的起始语言”。我投了赞成票。 :)
      • 好的,谢谢指正。我也赞成你的。
      猜你喜欢
      • 2020-09-02
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 2017-08-09
      • 2014-08-29
      • 1970-01-01
      相关资源
      最近更新 更多