は、ここに私のコードです:私が入力した場合、私はそれのように出て来てほしい(リバース(1 2 3 4)」)そう逆リストスキーム
(define (reverse list)
(if (null? list)
list
(list (reverse (cdr list)) (car list))))
( 4 3 2 1)しかし、今はそれが私に与えられていません。私は間違って何をしているのですか?どうすれば修正できますか?
は、ここに私のコードです:私が入力した場合、私はそれのように出て来てほしい(リバース(1 2 3 4)」)そう逆リストスキーム
(define (reverse list)
(if (null? list)
list
(list (reverse (cdr list)) (car list))))
( 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
を実装していないだろう現実に、そのための組み込みprocedureがあります。オスカーさんに似て
(define reverse
(lambda (l)
(let ((len (length l)))
(build-list len
(lambda (i)
(list-ref l (- len i 1)))))))
私は、パラメータ名として 'list'を使うことを勧めません。Schemeの字句スコープはその美しさの一部です。パラメータを「グローバル」関数とコンバートしないことをお勧めします。ポーズコードのエラーの1つ。 – GoZoner
はbuild-list
手順を使用してソリューションです。私はちょうどスキームを学習し始めているので、あなたが問題を見つけた場合には私を実感してください:)。
(define reverse?
(lambda (l)
(define reverse-aux?
(lambda (l col)
(cond
((null? l) (col))
(else
(reverse-aux? (cdr l)
(lambda()
(cons (car l) (col))))))))
(reverse-aux? l (lambda() (quote())))))
(reverse? '(1 2 3 4))
もう一つの答え:ここで
この1つは動作しますが、それは末尾再帰手続きではありません。
(define (rev lst)
(if (null? lst)
'()
(append (rev (cdr lst)) (car lst))))
ラムダの束と体を追加または充填する必要は実際にはありません。
(define (reverse lst)
(let loop ([lst lst] [lst-reversed '()])
(if (empty? lst)
lst-reversed
(loop (rest lst) (cons (first lst) lst-reversed)))))
これは基本的にlet
落札後loop
が結合オスカーの答え、のようにアキュムレータ引数でヘルパー機能を有すると同じアプローチである:という名前let
を使用して
(define (reverse items)
(if (null? items)
'()
(cons (reverse (cdr items)) (car items))))
あなたは 'cons 'の代わりに' append'を意味すると思います。 '(reverse(1 2 3))'を実行すると '((()。3)。2)。1)' – Jack
うん、そうだよ! @サルヴァトーレ・ラピサルダが正しい –
末尾再帰的なアプローチあなたが呼び出すことができる内部関数にしましょう。
私はこれは反復プロセス(末尾再帰を)説明する再帰的な手続きである末尾再帰と別のバージョン
(define (myrev2 l)
(define (loop l acc)
(if (null? l)
acc
(loop (cdr l) (append (list (car l)) acc))
)
)
(loop l '())
)
ここ
(define (myrev l)
(if (null? l)
'()
(append (myrev (cdr l)) (list (car l)))
)
)
、追加の代わりの短所を使用する方が良いと思いますスキームのリストを逆転させる方法
(define (reverse lst)
(define (go lst tail)
(if (null? lst) tail
(go (cdr lst) (cons (car lst) tail))))
(go lst())))
everseここで、(リスト1 2 3 4))
;; (reverse (list 1 2 3 4))
;; (go (list 1 2 3 4)())
;; (go (list 2 3 4) (list 1))
;; (go (list 3 4) (list 2 1))
;; (go (list 4) (list 3 2 1))
;; (go() (list 4 3 2 1))
;; (list 4 3 2 1)
再帰再帰的プロセス(尾ではないが記載されて再帰的手順である)(reverse2の置換モデルを用いてスキーム
(define (reverse2 lst)
(if (null? lst)()
(append (reverse2 (cdr lst)) (list (car lst)))))
(define (append l1 l2)
(if (null? l1) l2
(cons (car l1) (append (cdr l1) l2))))
にリストを反転させます(リスト1 2 3 4))
;; (reverse2 (list 1 2 3 4))
;; (append (reverse2 (list 2 3 4)) (list 1))
;; (append (append (reverse2 (list 3 4)) (list 2)) (list 1))
;; (append (append (append (reverse2 (list 4)) (list 3)) (list 2)) (list 1))
;; (append (append (append (append (reverse2()) (list 4)) (list 3)) (list 2)) (list 1))
;; (append (append (append (append() (list 4)) (list 3)) (list 2)) (list 1))
;; (append (append (append (list 4) (list 3)) (list 2)) (list 1))
;; (append (append (list 4 3) (list 2)) (list 1))
;; (append (list 4 3 2) (list 1))
;; (list 4 3 2 1)
あなたのコードは、循環リストと不適切なリストのどちらかまたは両方で動作すると思われますか? – GoZoner