2017-06-25 2 views
0

J'essaye de faire une fonction de schéma qui renvoie une liste «normale» d'une paire faite par des listes de listes.Liste des listes à la liste normale dans le schéma

Je suis en train de changer quelque chose comme ceci:

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

en quelque chose comme ceci:

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

J'ai essayé d'utiliser la récursivité queue, mais mon code retourne juste la même paire initiale .

Alors je l'ai fait, mais il ne fonctionne pas non plus et remaniements genre de la liste:

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

Que puis-je faire?

+0

Chaque liste est composée de paires. par exemple '(1 2 3)' est vraiment la structure '(1. (2. (3.())))'. Est-ce que [aplatir] (https://stackoverflow.com/questions/7313563/flatten-a-list-using-only-the-forms-in-the-little-schemer) que vous recherchez? – Sylwester

Répondre

0

Oscar Lopez vous a donné une bonne réponse, même si je testerais l1 avec liste? plutôt que de pairer, comme avec son code (aplatir '(1.2)) produirait (1 2), ce qui n'est probablement pas le résultat que vous souhaitez obtenir.

Avec cette correction son code peut être transformé en un pli:

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

Un problème avec cette façon de le faire est qu'il ajoute, ce qui est très efficace. Il est généralement préférable de contre dans l'accumulateur, puis inverser. Cela serait probablement plus optimal:

(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

Juste pour le plaisir, j'ai ajouté une autre implémentation très efficace à ma réponse, celle qui n'utilise pas les procédures de pliage. Aussi, je préfère utiliser 'pair?' Car 'list?' Est très inefficace, chaque fois qu'il doit traverser toute la liste juste pour vérifier si c'est une liste correcte. Et il est peu probable que OP s'attend à passer des listes inappropriées comme arguments, cela ressemble à un exercice d'apprentissage ... –

+0

Merci! C'était très utile: D –