私はリストを逆にしようとしています、これが私のコードです:
(define (reverse list)
(if (null? list)
list
(list (reverse (cdr list)) (car list))))
したがって、(reverse '(1 2 3 4)) と入力すると、(4 3 2 1) として出力されるようにしたいのですが、現在はそれが得られません。私は何を間違っていますか?どうすれば修正できますか?
リストを繰り返す自然な方法は、この問題を解決するための最良の方法ではありません。@lanceryが指摘した受け入れられた回答で示唆されているように、を使用append
することも良い考えではありません-とにかく、Schemeで自分のやり方を学んでいる場合は、自分でソリューションを実装しようとするのが最善です。 、しかし最初のヒント-パラメータ名として使用しないlist
でください。これは組み込みのプロシージャであり、上書きすることになります。他の名前を使用します。たとえば、lst
。
結果の先頭にある各要素の結果を累積するヘルパープロシージャを使用してリストを逆にする方が簡単です。これにより、リストが逆になります。ちなみに、ヘルパープロシージャは末尾再帰です。一般的な考え方は次のとおりです。空欄に記入してください。
(define (reverse lst)
(<???> lst '())) ; call the helper procedure
(define (reverse-aux lst acc)
(if <???> ; if the list is empty
<???> ; return the accumulator
(reverse-aux <???> ; advance the recursion over the list
(cons <???> <???>)))) ; cons current element with accumulator
もちろん、実際にreverse
は最初から実装することはありませんが、そのための組み込みの手順があります。
名前付きを使用した末尾再帰アプローチlet
:
(define (reverse lst)
(let loop ([lst lst] [lst-reversed '()])
(if (empty? lst)
lst-reversed
(loop (rest lst) (cons (first lst) lst-reversed)))))
これは基本的に、オスカーの回答のようにアキュムレータ引数を持つヘルパー関数を使用するのと同じアプローチです。ここでは、loop
バインディング後let
の let を呼び出すことができる内部関数にします。
build-list
手順を使用したソリューションは次のとおりです。
(define reverse
(lambda (l)
(let ((len (length l)))
(build-list len
(lambda (i)
(list-ref l (- len i 1)))))))
これは機能しますが、末尾再帰手順ではありません。
(define (rev lst)
(if (null? lst)
'()
(append (rev (cdr lst)) (car lst))))