7
votes

Comment puis-je renverser une liste?

Quelle est la fonction pour inverser une liste dans le schéma?

Il doit être capable de gérer des listes imbriquées. De sorte que si vous faites quelque chose comme (inverse '(a (bcd) e)) vous obtiendrez (e (bcd) a) comme sortie.

Comment dois-je aborder ce problème? Je ne cherche pas seulement une réponse, mais quelque chose qui m'aidera à apprendre.


2 commentaires

Meilleure réponse: (Définir (Rev1 LST) (FILETL CONS '() LST))


Habituellement, quand je vois " il doit être capable de gérer des listes imbriquées ", cela signifierait que (inverse '(A (BCD) E)) -> < Code> (E (DCB) A) , c'est-à-dire que les listes imbriquées sont également inversées. Qu'attendez-vous pour (inverse '(A (b c (d e)))) ? Je m'attendrais à ce que (((e d) c b) a) a) , mais l'exemple suggère que le résultat doit être ((b c (d e)) a) .


7 Réponses :


20
votes

Utilisation:

1st iteration
l=>(a (bcd)e)
car l => a
cdr l => (bcd)e
list(car l) =>(a)
------------------
reverse( cdr l)"+"(a)
------------------
2nd iteration
l=>((bcd)e)
car l => (bcd)
cdr l =>e
list(car l)=>(bcd)
--------------------
reverse(cdr l)"+"((bcd))+(a)
-----------------------
3rd iteration
l=>e
car l=> e
cdr l => nil
list (car l) =>(e)
-------------------------
(e (bcd)a)


6 commentaires

Notez que cette réponse est écrite dans la LISP commune, qui utilise nil au lieu de '() .


@erjiang n'est pas vraiment vrai - tandis que les lisp communs utilisent nil et le schéma ne le font pas, la fonction définie en haut de cette réponse est réellement schemise, pas de LISP commun. Vous auriez besoin de faire quelque chose comme (définir nil '()) afin de fonctionner cependant.


Cela fonctionne parfaitement avec une seule modification mineure (articles de retour au lieu de nil): (Définir les éléments (Rev items) (if (NULL? Éléments) (APPEND (APPEND (ARTICLES DE LA CDR))))))))))))) ) Je courais cela dans Petite Chez ( scheme.com )


Il existe également une procédure intégrée (inverse) qui renvoie le même résultat.


Pour éviter le problème de la liste NIL / vide, puisque vous savez déjà que L est vide de (NULL? L), ce cas pourrait simplement retourner l. Cela fonctionnera indépendamment de ce que NULL? chèques pour.


Sachez que cette mise en œuvre peut avoir des problèmes de performance. Jetez un coup d'œil à cela pour voir une version mieux performante de la mise en œuvre de la liste de la liste: CSS.SFU.ca/coursecentral/310/pwfong/lisp/2/Tutorial2.html



21
votes
(deep-reverse-2 '(a (b c d) e) '()); Which calls
(deep-reverse-2 '((b c d) e)  '(a))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d)  '(b)) '(a)))
(deep-reverse-2 '(e) (cons (deep-reverse-2 '(d)  '(c b)) '(a)))
(deep-reverse-2 '(e) (cons '(d c b) '(a)))
(deep-reverse-2 '(e)  '((d c b) a))
(deep-reverse-2 '() '(e (d c b) a))
'(e (d c b) a)

0 commentaires

2
votes

Ceci est une solution que vous pouvez faire une fonction inverse qui s'applique aux listes imbriquées: xxx

explication en pseudo-code:
Commencez par inverser la liste comme vous le feriez normalement Ensuite, pour chaque élément de la liste inversée:

- Si l'élément est une liste elle-même: appliquez la procédure de la procédure de manière récursive - sinon: ne touchez pas l'élément


0 commentaires

0
votes

J'ai utilisé le code similaire à Tri d'insertion :

(define deep-rev-list
  (lambda (l)
     (cond ((null? l) (quote ()))
           ((atom? (car l))
             (swap-till-end (carl) (deep-rev-list (cdr l))))
           (else
             (swap-till-end (deep-rev-list (car l)) (deep-rev-list (cdr l)))))))


(define swap-till-end
   (lambda (elm lst)
      (cond ((null? lst) (cons elm '()))
            (else
               (cons (car lst) (swap-till-end elm (cdr lst)))))))

(define atom?
  (lambda (x)
    (and (not (null? x)) (not (pair? x)))))


1 commentaires

Qu'est-ce que "le petit schemer" et "drracket"? Un livre et un outil en ligne, respectivement?



1
votes

Vous pouvez simplement inverser les éléments dans une liste à l'aide de FLIRR:

(foldr (lambda (a r) (append r (list a))) empty lst)


0 commentaires

1
votes

Ceci est une fonction inverse dans Raquette que j'aime beaucoup mieux que le schéma .

Il utilise la fonction de correspondance du modèle de correspondance uniquement. P>

(define/match (rev l)
    [('()) '()]
    [((list a ... b)) (cons b (rev a))])

> (rev '(a (b c d) e))
'(e (b c d) a)


1 commentaires

Cela utilise l'espace O (n ^ 2) et O (N ^ 2). Ainsi, plus la liste est longue aura moins probable que vous allez avoir une réponse avant que votre patience soit sortie ou que votre mémoire s'épuise.



0
votes

Ma solution:

(define (rvrs ls)
  (if (null? ls)
    empty
    (append (rvrs (cdr ls)) (cons (car ls) empty))))


1 commentaires

Une explication serait en ordre. E.G., quelle est l'idée? Comment est-ce différent des réponses précédentes?