2017-06-25 5 views
0

リストのリストで作られたペアから 'ノーマル'リストを返すスキーム関数を作ろうとしています。リストのリストをノーマルリストのリスト

私はこのようなものに変更しようとしている。このような何かに

((((((() 1) 2) 3) 4) (12 13 14)) ((((() 8) 9) 10) 11) (5 6 7)) 

を:

(1 2 3 4 12 13 14 8 9 10 11 5 6 7) 

私は末尾再帰を使用してみましたが、私のコードは、ちょうど同じ初期ペアを返します。 。

は、その後、私はこれをしなかったが、それはまた、動作しないとの種類のリストをシャッフル:

(define (tolist l1 lista) 
    (if (empty? (cdr lista)) 
     null 
     (if (empty? (car lista)) 
      (append l1 (cdr lista)) 
      (tolist (append l1 (car lista)) (list (cdr lista)))))) 

私は何ができますか?

+0

すべてのリストはペアで構成されています。 '(1 2 3)'は実際に ''(1。(2。(3。()))) ''という構造体です。それはあなたが探している( '' flatten'')(https://stackoverflow.com/questions/7313563/flatten-a-list-using-only-the-forms-in-the-little-schemer)ですか? – Sylwester

答えて

0

オスカー・ロペスはあなたに良い答えを与えましたが、私はリストでl1をテストしますか?彼のコード(flatten '(1.2))が(1,2)を生成するように、おそらくあなたの望む結果ではありません。

その補正では彼のコードが倍になってすることができます。それを行うためのこの方法で

(define (flatten seq) 
    (letrec ((flatten-with-append 
      (lambda (elt acc) ;; args as for SRFI-1 fold 
       (if (list? elt) 
        (fold flatten-with-append acc elt) 
        (append acc (list elt)))))) 
    (flatten-with-append seq '()))) 

一つの問題は、非常に効率的ではありませんこれは、それが追加されていることです。通常、アキュムレータに着目して逆にする方が良いです。これはより最適な可能性が高いでしょう:

(define (flatten seq) 
    (letrec ((flatten-with-cons 
      (lambda (elt acc) ;; args as for SRFI-1 fold 
       (if (list? elt) 
        (fold flatten-with-cons acc elt) 
        (cons elt acc))))) 
    (reverse (flatten-with-cons seq '())))) 
+0

ちょうど楽しみのために、折りたたみ手順を使用しない別の非常に効率的な実装を私の答えに追加しました。また、 'list?'はリスト全体を走査しなければならないたびに非常に効率が悪いので、適切なリストであるかどうかをチェックするために 'pair? 'を使うのが好きです。そして、OPが引数として不適切なリストを渡すことを期待している可能性は低いですが、これは学習の練習のように見えます... –

+0

ありがとう!それは非常に有用だった:D –

関連する問題