3

リストから奇数の値のみを返す必要があるため、car 関数と cdr 関数を使用してリストを壊そうとしています。Car がリストを返すかどうかをチェックし、次に car と cdr を使用してそれをさらに分割する再帰関数呼び出しがあります。それ以外の場合は、最初の要素を関数呼び出しチェックに渡すだけです。

特殊なケース (10 11 (12 13)) の問題は、car が 10 cdr を返す (11 (12 13)) ことです。

次に、2 回目の反復で car が (11 (12 13)) を返します。cdr は (11 (12 13)) を返します。

車とcdrを使用してリストをさらに分割するにはどうすればよいですか。最終的な回答で括弧を保持するだけでなく、奇数の整数値を持つリストのみを返す必要があります。

4

3 に答える 3

4

任意のネストされたリストで動作する必要がある関数の場合、最初にフラット リスト バージョン (この場合は filter-odd) を記述し、それを編集してネストされたバージョンを生成するのは簡単だと思います (filter-odd* と呼びます)。

通常のフィルター奇数の場合は最初

(define filter-odd
   (lambda (ls)
      (cond
        [(null? ls) '()]
        [(odd? (car ls)) (cons (car ls) (filter-odd (cdr ls)))]
        [else (filter-odd (cdr ls))])))

次に、filter-odd* について (演習として 1 つの右側を残します (ただし、質問から答えを知っているようです))

(define filter-odd*
   (lambda (ls)
      (cond
        [(null? ls) '()]
        [(list? (car ls)) #| Do something with both car and cdr of ls |# ]
        [(odd? (car ls)) (cons (car ls) (filter-odd* (cdr ls)))]
        [else (filter-odd* (cdr ls))])))

注意として、この設計パターンは、再帰的なプログラムを作成するのに役立ち、それをフラットなリストのみでの作業から任意の深いリストでの作業に変換するのに役立ちます。

于 2012-04-12T14:13:59.507 に答える
1

任意のレベルのネストを持つリストの一般的な解決策は次のとおりです。

(define (odds-list lst)
  (cond ((null? lst) '())                 ; the list is empty
        ((not (list? (car lst)))          ; first element is not a list
         (if (odd? (car lst))             ; element is odd
             (cons (car lst) (odds-list (cdr lst))) ; build the returned list
             (odds-list (cdr lst))))      ; element is even
        (else (cons (odds-list (car lst)) ; first element is a list
                    (odds-list (cdr lst))))))

次の 3 つのケースを考慮する必要があることに注意してください。

  1. リストが空の場合
  2. リストの最初の要素がリストでない場合
  3. リストの最初の要素がリストの場合

2 番目のケースでは、さらに 2 つのケースを考慮する必要があります。

  1. 要素が奇数の場合、返されたリストに追加します
  2. 要素が偶数の場合、それをスキップして次の要素に進みます
于 2012-04-12T15:15:41.427 に答える