-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個の奇数の正の整数の合計を見つけます

奇数だけを足す方法は考えられません。

4

5 に答える 5

1

いくつかのケースについて考えてみましょう。

1)(sumOdd 5)は何を返す必要がありますか?さて、それは5 + 3 + 1 = 9を返す必要があります。2)(sumOdd 6)は何を返す必要がありますか?まあ、それはまた5 + 3 + 1=9を返します。

これで、このアルゴリズムをさまざまな方法で記述できますが、これについて考えることにした1つの方法があります。

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番目のオプション:再帰。これを達成する方法はたくさんあります。たとえば、2 * nのリストを生成し、上記の手順を使用できます。

于 2013-03-01T00:58:42.207 に答える
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

この回答が興味深く、あまり混乱しないことを願っています。

于 2013-03-01T02:47:24.773 に答える
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))))))
于 2013-03-01T18:09:52.303 に答える
0

2 つの変数が必要です。1 つはまだ追加される奇数の数のカウンターを保持し、もう 1 つは現在の奇数を保持し、さらに使用された後に 2 ずつインクリメントされます。

(define (sum-odd n)
  (define (proc current start)
    (if (= current 0) 
        0
        (+ start (proc (- current 1) (+ start 2)) )))
    (proc n 1))
于 2013-03-01T15:55:58.013 に答える
0

さらに短い末尾再帰バージョン:

(define (sumOdd n)
  (let loop ((sum 0) (n n) (val 1))
    (if (= n 0)
        sum
        (loop (+ sum val) (- n 1) (+ val 2)))))
于 2013-03-01T19:17:28.637 に答える