这个函数的要求是找出1个数的因数,求出这些因数当中最大的前n个因数之和。
完整的要求是这样的:
思路
求因数的和,自然要有了因数才行。查了一下racket的reference,没有找到因数分解的函数,
这就意味着要动手写一个。
有了因数之后,也许需要排序,也许不需要,即使要排序,racket也有内置的排序函数可用。
然后,只需要取出前a个数再求和即可。取出前x个元素,这个可以直接使用racket内置的take
函数,
求和就不必说了,必定是有内置函数的。
至此,这个问题就很明了了,就是要写一个因数分解函数。
函数实现
因数分解基本上就是遍历,挨个尝试每个数能不能整除,在racket里边,这个必然是用递归实现。
Copy
1
2
3
4
5
6
7
8
9
10
11
(define (find-factors n)
;; 作者:徐工, 微博:@徐工徐工2020,头条:@徐工徐工
(define (_factors i x)
(cond
((or (>= 0 i)(>= 0 x))
'())
((zero? (remainder i x))
(cons x (_factors i (sub1 x))))
(else
(_factors i (sub1 x)))))
(_factors n n))
递归函数外面再套一层壳,这就齐活儿了。
求和函数就很简单了,直接调用racket内置函数就行了。
Copy
1
2
3
(define (sum-factor n a)
;; 作者:徐工, 微博:@徐工徐工2020,头条:@徐工徐工
(apply + (take (find-factors n) a)))
要是觉得写成2个函数太啰嗦了,那就直接合二为一。
Copy
1
2
3
4
5
6
7
8
9
10
11
(define (sum-factor n a)
;; 作者:徐工, 微博:@徐工徐工2020,头条:@徐工徐工
(define (_factors i x)
(cond
((or (>= 0 i)(>= 0 x))
'())
((zero? (remainder i x))
(cons x (_factors i (sub1 x))))
(else
(_factors i (sub1 x)))))
(apply + (take (_factors n n) a)))
测试结果
做了2组测试,(sum-factor 24 3) = 44
,(sum-factor 999 5) = 1507
,看上去一切正常。
benchmark一下,
Copy
1
2
3
4
(time
(void
(map (lambda (x) (sum-factor 999 5 ))
(make-list 10000 1 ))))
Dr Racket v8.10下跑10000次用时0.371s,似乎也不太慢。😂
收工。
文章作者
Jack Hsu
上次更新
2023-12-04
许可协议
Copyright © Jack Hsu. All Rights Reserved.