Scheme 用于返回平方数列表之和的Racket递归函数

Scheme 用于返回平方数列表之和的Racket递归函数,scheme,racket,Scheme,Racket,我对Racket还不熟悉,我正在尝试编写一个递归函数,它接受一个数n,并返回第一个n整数的平方和。例如,(此函数3)返回14,因为14是9+4+1+0 我试着创建两个单独的函数,一个是对每个数字进行平方运算,然后返回一个平方数列表,另一个是对列表进行求和。每个数字的平方函数为: (define (squared my-list) (cond [(empty? my-list) empty] [(zero? my-list) 0] [else (cons (e

我对Racket还不熟悉,我正在尝试编写一个递归函数,它接受一个数
n
,并返回第一个
n
整数的平方和。例如,
(此函数3)
返回14,因为14是9+4+1+0

我试着创建两个单独的函数,一个是对每个数字进行平方运算,然后返回一个平方数列表,另一个是对列表进行求和。每个数字的平方函数为:

(define (squared my-list)
  (cond [(empty? my-list) empty]
        [(zero? my-list) 0] 
        [else (cons (expt  my-list 2)
                    (cons (squared   (sub1 my-list)) empty))]))
如果我运行
(平方3)
返回
(cons 9(cons 4(cons 1(cons 0 empty))empty))

当我运行第二个函数(sum函数)时:

然后运行
(sum(squared 3))
我收到一条错误消息,因为
(squared 3)
在列表中返回一个额外的“cons”


如何解决此问题?

最简单的解决方案是使用封闭形式:

(define (sum-of-squares n)
  (* 1/6 n (+ n 1) (+ n n 1)))

信用证:

您在
平方中的逻辑有点不正确。我将逐条解释这些问题

[(empty? my-list) empty]
这没有任何意义,因为
我的列表
永远不会是一个列表。事实上,
我的列表
的名字不好。参数
squared
是一个数字,而不是一个列表。这一条款可以完全删除

[(zero? my-list) 0]
这是实际的终止情况,但不应返回
0
。记住,
squared
必须返回一个列表,而不是一个数字。此案例应返回

[else (cons (expt my-list 2)
            (cons (squared (sub1 my-list)) empty))]))
最后,这一条款过于复杂。你有正确的想法把新号码排在列表的其余部分,但是你反对的次数太多了。请记住,
(平方(sub1 my list))
的结果本身就是一个列表,
cons
的第二个参数是列表的其余部分。你不需要额外的缺点,你可以完全消除它

结合这些更改,您将得到以下结果,这符合您的要求:

(define (squared my-list)
  (if (zero? my-list) empty
      (cons (expt my-list 2)
            (squared (sub1 my-list)))))
(我还将
cond
替换为
if
,因为不再需要
cond
。)


这就是说,这段代码不是很吵闹。在函数编程中,你有一个好主意,把你的函数分成两个函数,函数应该只做一件事,但你可以进一步分解它!具体来说,你可以利用Racket内置的高阶函数,使这类事情变得非常简单

通过适当地组合和,可以替换整个
平方
函数。例如,以下内容将创建0–3之间的正方形列表

(map (curryr expt 2) (range 4)) 这将为您提供适当的
14
结果。显然,为了清晰起见,您可以将其封装在自己的函数中,但是一旦您了解了Racket的函数构造,上面的代码所做的事情就会清楚得多


(但是,我不确定是否允许你使用这些,因为你的问题看起来很像家庭作业。只是为了将来的参考和完整性而记下。)

一个用于提供正方形列表的函数和一个用于汇总列表的函数是不必要的。 这样就可以了,并且根据需要是递归的

(define (my-sq n)
(cond [(zero? n) 0]
      [else
       (+ (* n n) (my-sq (- n 1)))]))

(my-sq 3) -> 14

这听起来像是家庭作业。是否允许您使用诸如
foldl
map
之类的功能?确实如此。我已经走了这么远了,但还是很糟糕,因为有更多的犯人。不,我们还没有学会foldl和map。非常感谢,我真的很感激。解释这一点很有帮助。 (apply + (map (curryr expt 2) (range 4)))
(define (my-sq n)
(cond [(zero? n) 0]
      [else
       (+ (* n n) (my-sq (- n 1)))]))

(my-sq 3) -> 14