4

私はLispにかなり慣れていないので、これは練習問題の1つです。

まず、この問題は単純にscheme. 私はこれに答える方法がわかりません。
この質問の目的は、以下に示すように、文を入力として受け取り、それに含まれる奇数桁の数をカウントするcount-odd関数を作成することです。

(count-odd'(234 556 4 10 97)) 6

また

(カウント奇数 '(24680 42 88)) 0

可能であれば、高次関数、再帰、またはその両方を使用して、どのようにそれを行うことができますか?

4

5 に答える 5

4

完全な解決策ではなく、いくつかの指針を示します。

まず第一に、これを行うには 2 つの異なる方法があります。再帰または高階関数 + 再帰です。この場合は、単純再帰の方が理解しやすいと思います。

したがって、リストを取り込んで処理を行う関数が必要になります。

(define count-odd
  (lambda (ls) SOMETHING))

これは再帰的なので、リストを分割したいと思います

(define count-odd
  (lambda (ls)
    (let ((head (car ls)) (rest (cdr ls)))
      SOMETHING)))

これには問題があります。これは空のリスト (例: (count-odd '())) のエラーですが、それを修正する方法を説明します。ヒント、scheme の case 式を確認してください。空リストの確認と処理が簡単になります

今何かが私たちの再帰なので、次のようなものです:

(+ (if (is-odd head) 1 0) (Figure out how many odds are in rest))

それはあなたに何かを始めるための何かを与えるはずです。後で特定の質問がある場合は、お気軽にさらに質問を投稿してください。

于 2012-12-19T04:57:53.780 に答える
1

最初に他の回答ガイドを考慮して、自分でやってみてください。以下は、それを解決する別の方法です。テスト済みの完全なソリューションは次のとおりです。

(define (count-odd num_list)
    (if (null? num_list)
        0
        (+ (num_odds (car num_list)) (count-odd (cdr num_list)))))

(define (num_odds number)
    (if (zero? number)
        0
        (+ (if (odd? number) 1 0) (num_odds (quotient number 10)))))

どちらの手順も再帰的です。

  • count-oddnum_oddsリストの最初の要素を取得して、リストに要素がなくなるまで渡し続けます (これが基本ケース、null リストです)。

  • num_odds数値の奇数桁数を取得します。そうするために、常に数値が奇数かどうかを尋ねます。奇数の場合は 1 を追加し、奇数の場合は 0 を追加します。次に、数値を 10 で割って最下位桁を削除し (これにより、数値が奇数か偶数かを決定します)、次のように渡されます。新しい呼び出しへの引数。このプロセスは、数値がゼロになるまで繰り返されます (基本ケース)。

于 2012-12-19T13:49:06.217 に答える
0

高次の解にジャンプする前に、再帰のみを使用して手で問題を解いてみてください。そのためには、他の回答をご覧になることをお勧めします。それが終わったら、自由に使えるツールを使用して実用的な解決策を目指します。問題を 2 つの部分に分けます。

まず、数字のリストで正の整数を分割する方法。これは、入力数値に対する再帰的な手順です。これを行うにはいくつかの方法があります。最初に数値を文字列に変換する方法や、算術演算を使用して数字を抽出する方法などがあります。末尾再帰の実装で、後者を使用します。

(define (split-digits n)
  (let loop ((n n)
             (acc '()))
    (if (< n 10)
        (cons n acc)
        (loop (quotient n 10)
              (cons (remainder n 10) acc)))))

これにより、高次関数の観点から問題を解決できます。解決策の構造は、問題を手で解決するために使用される精神的プロセスを反映しています。

  1. まず、入力リスト内のすべての数値を反復処理します ( を使用map) 。
  2. 各数字をそれを構成する数字で分割します (を使用split-digits)
  3. これらの数字のうち奇数がいくつあるかを数えます。これにより、1 つの数字だけの部分的な解が得られます ( を使用count) 。
  4. map( を使用してapply)によって返されたリストにすべての部分解を追加します。

これはどのように見えるかです:

(define (count-odd lst)
  (apply +
         (map (lambda (x)
                (count odd? (split-digits x)))
              lst)))
于 2012-12-19T13:58:35.173 に答える
0

これもいい方法だと思います。

(define (count-odd sequence)
  (length (filter odd? sequence)))

(define (odd? num)
  (= (remainder num 2) 1))

(count-odd '(234 556 4 10 97))

これが役立つことを願って〜

(length sequence) はシーケンスの長さを返し、
(filter proc sequence) は proc を満たすすべての要素を含むシーケンスを返します。
そして、(odd? num) という関数を定義できます。

于 2012-12-20T09:08:30.637 に答える