Scheme groupSum函数

时间:2018-04-22 16:13:16

标签: scheme racket r5rs

我尝试编写一个Scheme函数,该函数接受两个参数,一个数字列表和另一个数字,如果列表的一个子集加起来,则返回true。

示例输出:

> (groupSum '(1 2 5) 7)
> #t
> (groupSum '(1 2 5) 4)
> f

到目前为止,我所能做的就是获取列表中所有数字的总和。我需要用我的代码来实现示例输出?

到目前为止,这是我的代码:

(define (groupSum elemList)
  (if
    (null? elemList)
    0
    (+ (car elemList) (groupSum (cdr elemList)))
  ))

我的代码返回的内容:

> (groupSum '(1 2 5))
> 8

1 个答案:

答案 0 :(得分:0)

所以你要问的是,给定列表的子集是否存在(在位置意义上,即保留重复,如果有的话),它们加起来给定的数字。

要通过子集是powerset函数的工作,除非我们想要跳出它并在检测到成功后立即返回#t。否则,最后只返回#f

在此网站上从one of my other answers扩充powerset功能,我们得到

(define (group-adds-to aL aN)
  (call/cc
   (lambda (......)  ;; 2.
     (letrec 
        ([...... (lambda (aL)  ;; 4.
           (cond
             [(empty? aL) (list empty)]
             [else
              (add-into   ;; 5b.
                        (powerset (rest aL))  ;; 3b.
                        (first aL))]))]

         [...... (lambda (r a)  ;; 6.       ; `r` is recursive result, `a` an element
           (cond
             [(empty? r) empty]             ; nothing to add `a` to
             [else
              (cons (add a (first r)) ;; 7. ; either add `a`,
                    (cons (first r)         ;   or not, to the first in `r`
                          (add-into  ;; 5a. ; and recursively proceed
                           (rest r)         ;   to add `a` into the rest of `r`
                           a )))]))]

         [......                      ;; 8.
                  (lambda (......)       ;; 9...
                     (let ([sum ......])   ;; 10...
                       (if (= sum aN)  ;; 11.
                           (return #t)  ;; 1.
                           sum)))])

       (powerset aL)  ;; 3a.
       #f))))   ;; 12.

填空;

测试:

> (group-adds-to '(1 2 5) 7)
#t
> (group-adds-to '(1 2 5) 4)
#f

如果需要,可以进行一些微不足道的更改,使#r5rs符合要求。

当然,通过使用更多内置函数,可以简化和缩短此代码。在这里摆脱call/cc也很简单。您还可以获得想象并添加检查以缩短临时列表,检测并删除不可能有助于成功结果的子组(子集)。

好的,如何填补空白。

  1. return?那是什么?
  2. 这是call/cc为我们设置的逃生延续。当( if )被调用时,;; 1.会立即返回值#t,作为整个group-adds-to函数调用的最终结果,无论是我们在这一点上的递归内部有多深。递归刚刚放弃,结果只是返回 如果从未调用过return,因为从未检测到等式(= sum aN) ;; 11.,递归将结束,#f将正常返回,作为函数体内的最后一个表达式,在;; 12.
  3. a,b。 powerset?什么是
  4. 这是我们定义的内部功能
  5. a,b。 add-into
  6. 它也在这里定义。
  7. add
  8. 是的。
  9. 自己动手。看看它是如何被使用的,在;; 7,它的论点是什么,它必须返回什么。
  10. 自己动手。你可以做到!