这是我到目前为止所做的:
(define sumOdd
(lambda(n)
(cond((> n 0)1)
((odd? n) (* (sumOdd n (-(* 2 n) 1)
输出看起来像这样:
(sumOdd 1) ==> 1
(sumOdd 4) ==> 1 + 3 + 5 + 7 ==> 16
(sumOdd 5) ==> 1 + 3 + 5 + 7 + 9 ==> 25
这就是我想要做的事情:找到前N个奇数正整数之和
我想不出只添加奇数的方法。
答案 0 :(得分:1)
让我们考虑几个案例:
1)(sumOdd 5)应该返回什么?好吧,它应该返回5 + 3 + 1 = 9。 2)(sumOdd 6)应该返回什么?那么,这也会返回5 + 3 + 1 = 9。
现在,我们可以用很多方法编写这个算法,但这是我决定考虑的一种方法:
我们要编写一个递归函数,从n开始,然后倒计时。如果n为奇数,我们希望将n添加到运行总计中,然后按 2 倒计时。我为什么倒数2?因为如果n是奇数,n - 2也是奇数。否则,如果n是偶数,我不想添加任何东西。我想确保继续递归,然后我得到一个奇数。我如何到达下一个奇数,从偶数开始倒计时?我减去1.我这样做,倒计时直到n <= 0.我不想要在我的运行总数中添加任何东西,所以我返回0.这就是算法看起来的样子像:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 2))))
(else (sumOdd (- n 1))))))
如果它对您有帮助,这里是一个稍微不同算法的更明确的例子:
(define sumOdd
(lambda (n)
(cond ((<= n 0) 0)
((odd? n) (+ n (sumOdd (- n 1))))
((even? n) (+ 0 (sumOdd (- n 1))))))) ; note that (even? n) can be replaced by `else' (if its not odd, it is even), and that (+ 0 ..) can also be left out
编辑:
我发现问题已经发生了一些变化。要求前N个正奇数整数,有几个选项。
第一个选项:数学!
(define sumOdd (lambda (n) (* n n)))
第二个选项:递归。有很多方法可以实现这一目标。例如,您可以生成2 * n的列表并使用上述过程。
答案 1 :(得分:1)
为了进一步阐述sum-odds
问题,你可以用更抽象的程序来解决它,这些程序结合起来积累了所需的答案。这不一定是最简单的解决方案,但它是有趣的并且捕获了一些在处理列表结构时常见的一般模式:
; the list of integers from n to m
(define (make-numbers n m)
(if (= n m) (list n) ; the sequence m..m is (m)
(cons n ; accumulate n to
(make-numbers (+ n 1) m)))) ; the sequence n+1..m
; the list of items satisfying predicate
(define (filter pred lst)
(if (null? lst) '() ; nothing filtered is nothing
(if (pred (car lst)) ; (car lst) is satisfactory
(cons (car lst) ; accumulate item (car lst)
(filter pred (cdr lst))) ; to the filtering of rest
(filter pred (cdr lst))))) ; skip item (car lst)
; the result of combining list items with procedure
(define (build-value proc base lst)
(if (null? lst) base ; building nothing is the base
(proc (car lst) ; apply procedure to (car lst)
(build-value proc base (cdr lst))))) ; and to the building of rest
; the sum of n first odds
(define (sum-odds n)
(if (negative? n) #f ; negatives aren't defined
(build-value + ; build values with +
0 ; build with 0 in base case
(filter odd? ; filter out even numbers
(make-numbers 1 n))))) ; make numbers 1..n
希望这个答案很有趣,而且不会太混乱。
答案 2 :(得分:0)
你需要有2个变量,一个用于保持计数器仍然要添加多少个奇数,另一个用于保存当前奇数,在另外使用后增加2:
(define (sum-odd n)
(define (proc current start)
(if (= current 0)
0
(+ start (proc (- current 1) (+ start 2)) )))
(proc n 1))
答案 3 :(得分:0)
这是一个很好的尾递归实现:
(define (sumOdd n)
(let summing ((total 0) (count 0) (next 1))
(cond ((= count n) total)
((odd? next) (summing (+ total next)
(+ count 1)
(+ next 1)))
(else (summing total count (+ next 1))))))
答案 4 :(得分:0)
更短的尾递归版本:
(define (sumOdd n)
(let loop ((sum 0) (n n) (val 1))
(if (= n 0)
sum
(loop (+ sum val) (- n 1) (+ val 2)))))