0

次の関数で再帰がどのように機能するかを誰かに説明してもらえますか? 具体的には、関数がその基本ケースに到達したときに何が起こるかに興味があります。また、このコードで名前付き let が使用されているのはなぜですか? (私は名前付き let に慣れていません)

(define (unzip list-of-pairs)
  (if (null? list-of-pairs)
   (cons '() '())
   (let ((unzipped (unzip (cdr list-of-pairs))))
         (cons (cons (car (car list-of-pairs)) (car unzipped))
               (cons (cdr (car list-of-pairs)) (cdr unzipped))))))
4

1 に答える 1

1

示されている手順には特別なことは何もありません。次の形式のリストを繰り返し処理しているだけです。

'((1 . 2) (3 . 4) (5 . 6))

唯一の「奇妙な」部分は、出力が通常の 1 つのリストではなく2 つのリストを作成していることです。ご存知のように、出力として単一のリストを作成する場合、基本ケースは次のとおりです。

(if (null? lst) '() ...)

しかし、ここでは 2 つのリストを同時に作成しているため、基本ケースは次のようになります。

(if (null? lst) (cons '() '()) ...)

問題のコードはnamedletを使用していません。それはただの古い庭の品種letであり、特別なことは何もありません。再帰呼び出しから 2 つの値を取得する必要がある場合、再帰を 1 回だけ呼び出したいので、これは便利です。

非効率であることを気にしないのであればlet、各ステップで再帰を 2 回呼び出すという代償を払って、を使用せずに手順を書くことができます。

(define (unzip list-of-pairs)
  (if (null? list-of-pairs)
      (cons '() '())
      (cons (cons (car (car list-of-pairs))
                  (car (unzip (cdr list-of-pairs))))
            (cons (cdr (car list-of-pairs))
                  (cdr (unzip (cdr list-of-pairs)))))))

もちろん、使用する利点はlet、二重再帰呼び出しを回避できることです。

于 2013-10-06T17:21:53.037 に答える