Précédent   Forum du club des développeurs et IT Pro > Autres langages > Langages fonctionnels > Lisp
Lisp Forum d'entraide sur la programmation en langages fonctionnels Lisp et Common Lisp
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 01/05/2011, 12h20   #1
alcibiade
Invité de passage
 
Inscription : mai 2008
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 24
Points : 3
Points : 3
Par défaut Parcours de listes et de sous listes.

Bonjour,

Je cherche une fonction pour parcourir des listes contenant ou pas des sous listes.

Par exemple :

(a ( b c) d (e f) (g h) i j k)

Ensuite je cherche à effectuer des comparaisons entre chaque atome et un autre atome rentré par l'utilisateur. La fonction sera récursive.

La fonction ressemblerait à cela :

Fonction (liste)

SI pas de liste alors renvoie nil
SI le premier élément n' est pas une liste, alors affiche le moi et continue avec fonction(liste (cdr argument))

SI le premier élément est une liste (donc sous liste) alors affiche moi son car et rentre dans cette liste. Affiche moi le car de cette sous liste.

Bref je ne sais pas si je suis bien clair, mais ce que je veux une fonction qui parcours une liste contenant des sous listes ou non. Cette fonction me servira à comparer des atomes entre en eux rajoutant par exemple un deuxième argument après l'argument liste et en le comparent avec les atomes contenus dans cette liste...

Toutes mes tentatives ont étaient des échecs, notamment par la mauvaise utilisation de cond.

Voila et merci d'avance pour vos réponses.
alcibiade est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 12h23   #2
Trap D
Rédacteur/Modérateur
 
Avatar de Trap D
 
Inscription : septembre 2003
Messages : 4 437
Détails du profil
Informations forums :
Inscription : septembre 2003
Messages : 4 437
Points : 5 301
Points : 5 301
Citation:
Envoyé par alcibiade Voir le message
Toutes mes tentatives ont étaient des échecs, notamment par la mauvaise utilisation de cond.
Eh bien, montre ce code qui ne marche pas, on te dira peut-être pourquoi.
__________________
"La haine seule fait des choix" - Koan Zen
"Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
"Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
Faites du Prolog, ça vous changera les idées !
Ma page Prolog
Mes codes sources commentés

Mon avatar : Intérieur avec jeune femme de Vilhelm Hammershoi
Trap D est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 12h49   #3
alcibiade
Invité de passage
 
Inscription : mai 2008
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 24
Points : 3
Points : 3
Voici mon bout de code

Code :
1
2
3
4
5
6
7
8
9
10
11
(defun parcours(liste)
   (cond
      ((not liste)())
      ((equal(listp(car liste))nil)(car liste)(parcours(cdr liste)))   
      ((equal(listp(car liste))T)(parcours(cdr liste)))
   )
)
PARCOURS
Break 3 [5]> (parcours liste)
NIL
Break 3 [5]>
J'imagine que beaucoup de choses manquent surement... La mauvaise utilisation du cond et des clauses on surement une responsabilité dans le mauvais fonctionnement de cette fonction. Ceci dit je pense que l'idée générale n'est pas mauvaise, à vous de voir
alcibiade est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 18h09   #4
Trap D
Rédacteur/Modérateur
 
Avatar de Trap D
 
Inscription : septembre 2003
Messages : 4 437
Détails du profil
Informations forums :
Inscription : septembre 2003
Messages : 4 437
Points : 5 301
Points : 5 301
Je ne connais pas bien la syntaxe du Lisp, donc je marche un peu sur des oeufs.

Si j'ai bien compris tu voudrais que dans un premier temps ta fonction affiche (a b c d e f g h i j k) a partir de (a ( b c) d (e f) (g h) i j k)

A partir de ça, la première clause du cond me parait correcte.
Pour la seconde, il me semble que tu devrais écrire (cons (car liste) (parcours de cdr liste)))

pour la troisième, il faut que tu concatène le parcours du premier élélment de la liste avec le parcours du reste de la liste, ça se traduit par (append (parcours (car liste)) (parcours (cdr liste)))
__________________
"La haine seule fait des choix" - Koan Zen
"Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
"Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
Faites du Prolog, ça vous changera les idées !
Ma page Prolog
Mes codes sources commentés

Mon avatar : Intérieur avec jeune femme de Vilhelm Hammershoi
Trap D est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 12h42   #5
alcibiade
Invité de passage
 
Inscription : mai 2008
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 24
Points : 3
Points : 3
Merci pour votre réponse,

Je vais essayer ce que vous m'avez conseiller. J'ai par ailleurs trouvé une autre solution à ce problème. Une fonction qui parcours les listes plates si le car d'une liste est un atome, mais si le car de la liste est une liste (donc sous liste) la fonction fait la même chose, mais cette fois avec le car de liste.

Bref voici le code:
La fonction qui parcours les listes plates:
Code :
1
2
3
4
5
6
7
(defun parcours(liste)
(cond
((not liste)())
((eq(listp(car liste))nil)(and (print (car liste))(parcours(cdr liste))))
)
)
La fonction qui parcours tout:
Code :
1
2
3
4
5
6
7
8
9
(defun parcours_tout(liste)
(cond
((not liste)())
((eq(atom(car liste))T)(parcours liste))
((eq(listp(car liste))T)(and(parcours(car liste))(parcours_tout(cdr liste))))

)
)
Cette fonction ne marche toujours pas. Par exemple avec ((d e f) a b c) cette fonction ne me retourne que D E F nil elle ne continue pas avec a b c. Le seul moyen que j'ai trouvé pour qu'elle le fasse c'est de placer
Code :
 ((eq(listp(car liste))T)(and(parcours(car liste))(parcours_tout(cdr liste))))
hors du cond. Mais dans ce cas j'ai un dépassement de pile. Bref je vais essayer ce que vous m'avez conseiller et je reviens après.
Merci encore en tout cas.
alcibiade est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 14h21   #6
mehdidc
Invité régulier
 
Inscription : mai 2008
Messages : 10
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 10
Points : 6
Points : 6
Citation:
Envoyé par alcibiade Voir le message
Merci pour votre réponse,

Je vais essayer ce que vous m'avez conseiller. J'ai par ailleurs trouvé une autre solution à ce problème. Une fonction qui parcours les listes plates si le car d'une liste est un atome, mais si le car de la liste est une liste (donc sous liste) la fonction fait la même chose, mais cette fois avec le car de liste.

Bref voici le code:
La fonction qui parcours les listes plates:
Code :
1
2
3
4
5
6
7
(defun parcours(liste)
(cond
((not liste)())
((eq(listp(car liste))nil)(and (print (car liste))(parcours(cdr liste))))
)
)
La fonction qui parcours tout:
Code :
1
2
3
4
5
6
7
8
9
(defun parcours_tout(liste)
(cond
((not liste)())
((eq(atom(car liste))T)(parcours liste))
((eq(listp(car liste))T)(and(parcours(car liste))(parcours_tout(cdr liste))))

)
)
Cette fonction ne marche toujours pas. Par exemple avec ((d e f) a b c) cette fonction ne me retourne que D E F nil elle ne continue pas avec a b c. Le seul moyen que j'ai trouvé pour qu'elle le fasse c'est de placer
Code :
 ((eq(listp(car liste))T)(and(parcours(car liste))(parcours_tout(cdr liste))))
hors du cond. Mais dans ce cas j'ai un dépassement de pile. Bref je vais essayer ce que vous m'avez conseiller et je reviens après.
Merci encore en tout cas.
Bonjour,
voici une version qui marche, normalement.c'est à tester:
Code :
1
2
3
4
5
6
7
8
(defun parcours(L)
        (cond
                ((eq L nil) nil)
                ((listp (car L)) (prog1 (parcours (car L)) (parcours (cdr L))))
                (T (prog1 (print (car L)) (parcours (cdr L))))
        )
)
mehdidc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/05/2011, 23h53   #7
alcibiade
Invité de passage
 
Inscription : mai 2008
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 24
Points : 3
Points : 3
Merci pour vos réponses apparemment le dernier bout de code marche très bien, mis à part un doublon du premier élément quand j'appelle la fonction.

Par exemple :

(a (b c) d e f)
a
b
c
d
e
f
a

Mais ce que je voudrais savoir surtout c'est pourquoi mon code ne marchait pas, j'ai réessayer plusieurs fois ma chance avant de tenter votre bout de code mais je n'ai rien trouvé... Je pense tout d'abord que la première condition de mon cond était fausse.
En effet Trap D cette clause est fausse car elle dit:
--> si pas de liste sortir de la récursivité
Hors si je vide ma première sous liste (a b), et qu'une fois le b parti je me retrouve avec () donc pas de liste, et je me retrouve sorti de ma récursivité sans avoir tester le reste de ma liste. Est-ce que j'ai bien raison?

Bref je vous remercie pour vos réponses, mais si puis-je avoir plus de précisions sur ce que fait notamment prog1 , je pense que cela m'aiderait.

Merci encore.
alcibiade est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/05/2011, 07h43   #8
Trap D
Rédacteur/Modérateur
 
Avatar de Trap D
 
Inscription : septembre 2003
Messages : 4 437
Détails du profil
Informations forums :
Inscription : septembre 2003
Messages : 4 437
Points : 5 301
Points : 5 301
Le parcours de liste peut s'écrire en gros comme ceci :
Citation:
parcours de liste
si liste vide alors renvoyer la liste vide
si premier element est une liste alors enchaîner le parcours du premier element avec le parcours du reste de la liste
sinon concatener le premier élément avec le parcours du reste de la liste
Je vous invite à dérouler cet algo "à la main" pour vote exemple (a (b c) d e f) vous verrez que l'action pour la liste vide est correct.
__________________
"La haine seule fait des choix" - Koan Zen
"Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
"Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
Faites du Prolog, ça vous changera les idées !
Ma page Prolog
Mes codes sources commentés

Mon avatar : Intérieur avec jeune femme de Vilhelm Hammershoi
Trap D est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/05/2011, 23h19   #9
alcibiade
Invité de passage
 
Inscription : mai 2008
Messages : 24
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 24
Points : 3
Points : 3
Par défaut RESOLUE ! (presque)

Bonjour,

Même si vous m'avez bien aider je souhaite finir ce poste par une version que j'ai trouvé en fouillant un peu dans mes cours et en bidouillant un peu:
Code :
1
2
3
4
5
6
7
8
(defun parcoursab(liste)
(cond
((not liste) nil)
((consp(car liste))( print(parcoursab(car liste))(parcoursab(cdr liste))))
(t(print(car liste))(parcoursab(cdr liste)))
)
)
Mea culpa pour le (not liste) nil. En effet Trap D vous aviez raison il n'y a aucun problème avec le premier test du cond. Cette fonction n'est pas parfaite car elle affiche les nil present à la fin de chaque liste ou sous-listes, mais il reste tout de même assez bonne dans l'ensemble.
Merci encore pour votre aide en esperant que ce poste pourra servir dans le futur.
alcibiade est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 05h38.


 
 
 
 
Partenaires

Hébergement Web