这个问题可能有点复杂,但是我不确定,这个问题对我来说似乎至少很复杂。我本质上是在尝试编写由(listof Num)和Num组成的一段代码。如果L是表示n的埃及分数,则我的函数将输出#true。埃及分数是分子为1的不同分数的总和,以防万一某些人不知道。目前,我已经开始编写代码,并且有解决该问题的想法,但不知道下一步该怎么做。我非常希望答案保持现在的格式。我正在练习递归并尝试对其进行改进。
在我的代码中,我有一个基本情况,如果列表为空,则输出#false。
然后我写了一个情况,如果重复L中的任何值,则函数输出#false
然后我写了一个情况,如果L的所有值的总和等于n的值,则该函数将返回#true。
我的最后一种情况只是输出#false,这意味着L中的值之和不等于n。
我的代码的思考过程似乎是正确的,但是我的代码实际上不起作用。 这是我的代码
(define (egyptian? L n)
(cond
[(empty? L) #false]
[(equal? (first L) (first (rest L)) (egyptian? (rest L))) #false]
[( = n (+ (first L) (egyptian? (rest L))))#true]
[else #false]))
这是函数应该输出的内容
(check-expect (egyptian? (list 1/2 1/3 1/6) 1) #true)
(check-expect (egyptian? (list 1/2 1/4 1/5 1/20) 1) #true)
(check-expect (egyptian? (list 1/2 1/3 1/4 1/5 1/6) 1.5) #false)
(check-expect (egyptian? (list 1/2 1/2 1/2 1/2) 1) #false)
如您所见,前两种情况为#true,因为列表中值的总和等于“ n”。第三种情况是不正确的,因为列表中的值之和不等于“ n”。第四种情况是不正确的,因为列表中的值是重复的。希望我能提供有关我正在努力解决的问题的足够信息。
答案 0 :(得分:2)
对此(以及许多其他问题)的最佳策略是将问题分成较小的部分。让我们从查找列表中所有数字的总和开始,这应该很容易:
(define (sum L)
(if (empty? L)
0
(+ (first L)
(sum (rest L)))))
现在,让我们编写一个过程来检查列表中的元素是否唯一。这并不像将列表中的一项与下一项检查一样简单,重复的项可能在列表中的任何地方!
(define (unique? L)
(cond ((empty? L) #true)
((member (first L) (rest L)) #false)
(else (unique? (rest L)))))
有了这些程序,我们的主要问题就变得难以解决:
(define (egyptian? L n)
(and (unique? L)
(= (sum L) n)))
现在您知道,功能组合的概念多么强大!在您尝试的解决方案中,您在一个过程中混合了三个不同问题的代码,这使事情变得很难理解。
将问题分解为较小部分的另一个不错的效果是,您可以稍后切换实现,以获得更有效的解决方案。例如,这就是我们在惯用的球拍中编写sum
和unique?
过程的方式:
(define (sum L)
(apply + L))
(define (unique? L)
(= (length L) (set-count (list->set L))))