2013-02-04 2 views
1

Dans Scheme/Lisp, j'essaie de créer une fonction qui convertit une liste en une liste circulaire. Par conséquent, je crois que j'ai besoin de construire un flux infini dans lequel la queue de la liste pointe vers la tête de la liste.Flux de schémas et listes circulaires

Voici mon code à ce jour:

(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)))) 

Toute aide est grandement appréciée.

Répondre

4

Non, vous n'avez pas besoin de flux pour créer une liste circulaire.

Il existe deux approches pour créer des listes circulaires, l'approche Scheme standard et l'approche Racket (puisque les conse de Racket sont immuables). Je vais regarder des exemples en utilisant SRFI 1circular-list fonction. Voici l'implémentation de référence:

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

Qu'est-ce que cela fait est de trouver la dernière paire dans la liste des valeurs données, et set-cdr! s revenir au début de cette liste. Assez simple, non?

Dans Racket, les conses sont immuables, donc set-cdr! n'existe pas. Ainsi, au lieu, Racket il fait ainsi:

(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))) 

Cette fonction utilise de Racket make-reader-graph pour gérer les cycles. Très chouette. :-)

Questions connexes