在Scheme中创建集合的分区

在Scheme中创建集合的分区,scheme,racket,partition-problem,Scheme,Racket,Partition Problem,我对整个计划还不太熟悉,我在为学校安排作业时遇到了一些问题。所以,请不要给出完整的答案,只是寻求一点见解或正确的方向,这样我就可以自己解决这个问题 问题如下:给定一个数字列表,确定是否可以从这些等价和和和#项的数字中生成两个子集。例如,如果给定的集合是(11),那么我的程序应该返回#t,否则返回#f 以下是我到目前为止所写的内容(尽管目前没有输出) 我的函数应该递归地向子集1(s1,l1)或子集2(s2,l2)添加项,直到它到达基本情况,在这种情况下,它确定子集的大小和总和是否相等。我觉得我的逻

我对整个计划还不太熟悉,我在为学校安排作业时遇到了一些问题。所以,请不要给出完整的答案,只是寻求一点见解或正确的方向,这样我就可以自己解决这个问题

问题如下:给定一个数字列表,确定是否可以从这些等价和和和#项的数字中生成两个子集。例如,如果给定的集合是(11),那么我的程序应该返回#t,否则返回#f

以下是我到目前为止所写的内容(尽管目前没有输出)

我的函数应该递归地向子集1(s1,l1)或子集2(s2,l2)添加项,直到它到达基本情况,在这种情况下,它确定子集的大小和总和是否相等。我觉得我的逻辑是正确的,但我不确定如何在方案中正确实施这些想法


我应该补充一点,作为赋值的一部分,我必须使用递归。我希望DrRacket提供更多的调试信息,因为当我点击run时,它不会给出任何错误,也不会给出任何输出。

对于第一步,您可能希望避免尝试将“子集”逻辑与“将两个子集添加到同一个值”逻辑耦合。小程序比长程序更容易编写

但这可能是一个复杂的问题

一种方法叫做“一厢情愿”。我们将从最后一步开始工作:解决这个问题的最后一步是什么?比较相同长度的两个子集之和是否为相同的值。那么,让我们来解决这个问题。然后我们对相同长度的所有子集都这样做。但现在我们需要知道:相同长度的所有子集组是什么?如果我们解决了这个问题,那么一切都结束了。让我们来解决这个问题。然后我们将其应用于所有子集的集合。但现在我们需要知道:如何得到所有子集的集合?如果我们解决了这个问题,那么一切都结束了。我们将把它应用到我们的场景中。但现在我们需要知道:我们的场景是什么-哦这就是问题本身。所以我们结束了

事实上,在细节上有点棘手,但是通过上面的阐述,我认为你可以看到这个链条的逻辑:

(find-first-equal-sum ; we can stop as soon as #t, if there is #t
  (make-pairs ; problem only wants us to consider pairs
    (sum-subsets ;we need sums eventually
       (at-least-two-in-a-group ; can't make pairs without at least two in a group
        (group-by-length ; only care about matching subsets of the same length
         (at-least-length-2 ; singles can't match because each element of a set is unique
          (subsets problem-set)))))))
注意:在发布之前,我确实编写了这个程序并进行了测试。上述“大纲”直接从DrRacket复制。

Issues 您的代码中存在一些问题

弗斯特 这将创建一个列表的列表:

(list '(7 5))  ; => ((7 5))
其中的
cdr
始终是一个空列表

(cdr (list '(7 5)))  ; => ()
以这种方式创建单个列表:

(define l (list 7 5))
(define l '(7 5))
或者这样:

(define l (list 7 5))
(define l '(7 5))
第二 在应用程序的方案中使用括号。这:

(#t)
表示“执行功能
#t
”。但是
#t
不是一个函数,它是一个布尔值。和布尔值无法执行

您可以直接返回布尔值

#t
或者您可以返回一个返回值的函数

(lambda () #t)
但你不能执行真实的

第三
中存在相同的问题。以下代码:

(or ((two-subsets (cdr l) (+ s1 1) s2 (+ l1 1) l2)
     (two-subsets (cdr l) s1 (+s2 1) l1 (+ l2 1))))
表示:
两个子集必须返回一个函数。第一个
两个子集
调用返回的函数与第二个
两个子集
调用返回的函数一起执行。然后将单个结果值传递给
。这可能不是你想要的

如果要
两个调用
两个子集的两个返回值,必须删除两个括号

(or (two-subsets (cdr l) (+ s1 1) s2 (+ l1 1) l2)
    (two-subsets (cdr l) s1 (+s2 1) l1 (+ l2 1)))
提示
  • 定义一个与最终条件匹配的函数。函数接受两个列表参数并检查它们是否具有相同的大小(
    length
    )和总和(您可以使用
    apply
    将列表传递给
    +
  • 编写一个遍历所有可能子集的函数。并使用每个组合调用匹配函数。在Scheme中,迭代是通过递归完成的。要么定义一个调用自身的函数,要么使用命名的
    let

非常感谢您周到的回复!!但是我应该补充一点,我必须使用递归来解决这个问题。你的详细描述确实帮助我更清楚地理解和思考这个问题。非常感谢。我想你会发现这些过程中的大多数都是递归的,因为它们在列表上运行。例如,
子集
过程是高度递归的。