如何使用powerset函数来查找子集的总和

时间:2015-04-18 20:18:03

标签: scheme racket

对于这个问题,我有一个称为powerset功能的功能

(define (powerset set)
  (if (null? set)
      '(())
      (let ((rest (powerset (cdr set))))
        (append (map (lambda (element) (cons (car set) element))
                     rest)
                rest))))

如果从powerset函数生成的子集的和等于作为参数传入的总和,我想使用该函数返回true。我认为我有正确的想法,但我不知道如何实施。我知道这个函数生成的列表应该一次传递给另一个函数1子集。在该函数中,我想将这些值一起添加到子集中,并查看它们是否等于总和。到目前为止,我知道这是错误的。

(define (group list sum)
 (cond((null? list) #f)
      ((equal? (apply + (powerset list)) sum)#t)
      (else (group((powerset list))sum)) ))

所以我需要一个调用powerset一次的函数,并将列表一次传递给另一个函数,该函数将子集的总和与作为总和传递的值相比较。

例如,如果我打电话:

(group '(1 2 4 5) 9)

我想要返回#t,因为总和的子集(4,5)等于9.如果您知道如何使用powerset并且可以在解决此问题时显示示例,那么将不胜感激。

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是在子集列表上映射sum函数,这将为您提供一个列表,其元素对应于每个子集的总和。然后,您可以检查此总和列表中的任何元素是否等于提供的目标总和。

这样做的一种方法是这样的:首先我们需要一个函数来对列表求和。我们可以使用折叠:

(define (sum set)
    (fold-right + 0 set))

现在,我们定义一个函数,如果给定元素包含在提供的列表中,则返回true,否则返回false:

(define (contains n set)
    (if (null? set)
        #f
        (if (= (car set) n)
            #t
            (contains n (cdr set)))))

(我不是Scheme的专家所以我不确定这是否是内置的东西。)

通过这个定义,我们可以编写你想要的功能:

(define (group set n)
    (contains n (map sum (powerset set))))

您可以测试您的示例(group '(1 2 4 5) 9)为我们提供#t