我有一个函数和数字,用于计算平方数字的总和 并且停止检查数字和系列是否始终到达其中一个停止数的功能。 {0 1 4 16 20 37 42 58 89 145}
如何创建一个名为's_series'的函数,该函数返回包含总和的列表,直到达到停止数。
ex :- (s_series 130)
(10 1)
我的代码
(define (s_series x)
(let ((number (sum-of-digits x)))
(if (number stop(number) 1)
((let (L '(sum)))
(s_series sum ))
L
))
我该如何解决这个问题并让它发挥作用?
答案 0 :(得分:1)
首先如果您正在收集sum-of-squared-digits
,那么stop?
函数应该收取这笔费用而不是直接计算:
(define (stop? value)
(if (memv value '(0 1 4 16 20 37 42 58 89 145)) #t #f))
注意我使用memv
,因为我们知道我们正在比较数字,memv
使用eqv?
进行比较,因此是作业的正确“成员”函数。此外,我不在此处使用sum-of-squared-digits
来对每个元素执行两次操作。
在SRFI-1列表库中有一个名为unfold
的函数:
(require srfi/1) ; In #!r6rs you import (srfi :1) but I assume #lang racket
(define (s-series start)
(unfold stop? ; stop if the sum is accodring to stop?
values ; no term transformation
sum-of-squared-digits ; how to make th enext value
(sum-of-squared-digits start) ; omit the first value
(lambda (v) (list v)))) ; keep the stop value
(s-series 120)
; ==> (5 25 29 85 89)
答案 1 :(得分:0)
当然,推荐的方法是使用现有程序(例如unfold
)来解决您的问题。这是函数式编程所鼓励的思维方式。为了完整起见,让我们看看我们如何只使用基本操作编写一个等效的解决方案,以及我们previously定义的过程:
(define (s_series n)
(let ((sum (sum-of-digits n)))
(if (stop? n)
(list sum)
(cons sum (s_series sum)))))
按预期工作:
(s_series 120)
=> '(5 25 29 85 89)