1

Scheme/Lisp で、リストを循環リストに変換する関数を作成しようとしています。したがって、リストの末尾がリストの先頭を指す無限ストリームを構築する必要があると思います。

これまでの私のコードは次のとおりです。

(define (rotate-list l1 l1copy)
  (if (null? (force (cdr l1)))
      (cons (car l1) (delay l1copy)))
      (cons (car l1) (delay (rotate-list (force (cdr l1)) l1copy))))

すべてのヘルプは大歓迎です。

4

1 に答える 1

5

いいえ、循環リストを作成するためにストリームは必要ありません。

循環リストを作成するには、標準の Scheme アプローチと Racket アプローチの 2 つのアプローチがあります (Racket の conses は不変であるため)。SRFI 1circular-list機能を使った例を見ていきます。参照実装は次のとおりです。

(define (circular-list val1 . vals)
  (let ((ans (cons val1 vals)))
    (set-cdr! (last-pair ans) ans)
    ans))

これは、指定された値のリストの最後のペアを見つけて、set-cdr!そのリストの先頭に戻すことです。かなり簡単ですよね?

Racket では、cons は不変であるため、set-cdr!存在しません。代わりに、Racket は次のようにします。

(define (circular-list val1 . vals)
  (let ([ph (make-placeholder #f)])
    (placeholder-set! ph
      (cons val1 (let loop ([vals vals])
                   (if (null? vals)
                     ph
                     (cons (car vals) (loop (cdr vals)))))))
    (make-reader-graph ph)))

これは Racket のmake-reader-graph関数を使用してサイクルを処理します。とても気の利いた。:-)

于 2013-02-04T02:28:44.830 に答える