2013-03-01 67 views
-1

这里工作是我迄今所做的:似乎无法得到这个功能在方案

(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个奇数正整数的总和

我想不出只能添加奇数的方法。

+1

你的括号不平衡。 – Necto 2013-03-01 13:51:51

回答

1

让我们想想一对夫妇的情况:

1)应该采取什么(sumOdd 5)返回?那么,它应该返回5 + 3 + 1 = 9. 2)应该(sumOdd 6)返回什么?嗯,这也将返回5 + 3 + 1 = 9

现在,我们可以写这个算法了很多办法,但这里有一个方法我已经决定要想一想:

我们要去编写一个递归函数,从n开始,然后倒计时。如果n是奇数,我们希望将n加到我们的运行总数中,然后通过倒计数。为什么我倒数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列表并使用上述过程。

+0

+1数学版 – uselpa 2013-03-01 19:16:15

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 

希望这回答很有趣,不是太混乱。

+1

感谢您花时间回答这个问题,实际上帮助我解决了另一个问题 – JimTom 2013-03-01 15:17:18

0

你需要有2个变量,其中一个保留的许多奇数如何仍有待添加计数器和另一个持有其得到由2除了使用后增加当前奇数:

(define (sum-odd n) 
    (define (proc current start) 
    (if (= current 0) 
     0 
     (+ start (proc (- current 1) (+ start 2))))) 
    (proc n 1)) 
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)))))) 
0

甚至更​​短的尾递归版本:

(define (sumOdd n) 
    (let loop ((sum 0) (n n) (val 1)) 
    (if (= n 0) 
     sum 
     (loop (+ sum val) (- n 1) (+ val 2)))))