【问题标题】:Scheme groupSum Function方案 groupSum 函数
【发布时间】:2018-10-02 17:32:45
【问题描述】:

我正在尝试编写一个 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

【问题讨论】:

    标签: scheme racket r5rs


    【解决方案1】:

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

    遍历子集是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. 自己动手。你可以做到的!

    【讨论】:

    • 感谢您的帮助!我是Scheme的新手,所以我仍然不太了解它。我应该在空白处做什么?
    • 仔细阅读代码并将缺少的内容放在那里。 :) 如果你知道 Scheme,那就很容易了。如果您不这样做,那么 SO 不是可以教给您的地方,对不起。如果您有具体问题,请离开。 :)
    • 但是首先,让我明白我的方向,你明白这个“powerset”的东西与你的问题有什么关系吗?
    • 是的,“powerset”允许您获取给定集合的子集?这就是我要针对这个问题做的事情,以检查集合中所有可能的数字总和。
    • 完全正确。到目前为止,我们保留了它们的总和,而不是保留子集...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 2020-07-04
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多