IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Pascal Discussion :

Concaténer deux listes


Sujet :

Pascal

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut Concaténer deux listes
    Bonjour

    Voici mon problème : je cherche à concaténer 2 listes par l'intermédiaire d'une fonction.
    Voici ce que j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    Type
       liste_elts=^doublet;
       doublet=record
          element:integer;
          suivant:liste_elts;
       end;
     
    Function concat(l1,l2:liste_elts):liste_elts;
    Var
       l:liste_elts;
    Begin
       l:=l1;
       while (l^.suivant <> nil) do
          l:=l^.suivant;
       l^.suivant:=l2;
       concat:=l1;
    End;
    Bon, en gros : je me place à la fin de la liste l1, et je raccord la liste l2 au bout de celle-ci. Je pense que ça, ça ne pose pas de problème.
    Mon problème est dans le renvoi de concat : que dois-je renvoyer à la fonction ? l1 ? l ?
    Visiblement, d'après mes tests, ça serait encore autre chose, mais je ne vois pas quoi...
    Actuellement :
    * lorsque je renvoie l1, il me renvoie le l1 original
    * lorsque je renvoie l, il me renvoie l2...


    Merci de votre aide...

  2. #2
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Pour moi ta fonction marche, même si je ne l'ai pas testé. l1 et l2 ne sont pas modifiés, ce qui est normal, et la valeur que tu dois retourner est bien l1. La boucle m'a l'air bonne, tu t'arretes sur le dernier élément et tu assignes le champ suivant à l2.

    Es-tu sûr que l1 n'est pas modifié ? Normalement le début est le même, juste la fin change. Quant à l2 tu peux le faire pointer à null, après l'appel à ta procédure, si tout s'est bien passé tu n'auras pas de perte de données...
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  3. #3
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    Il y a une chose qui est bizarre...
    En fait, pour tester cette fonction :
    * je fais afficher l1
    * je fais afficher l2
    * je concatène les 2 listes
    * je fais afficher l3 (la nouvelle liste)
    * j'utilise une autre fonction que j'ai codé plus haut dans mon devoir pour avoir la longueur de la liste... et en l'occurence, cette fonction me renvoie comme longueur de l3 : la longueur de l1
    Qui plus est, la liste l3 est strictement identique à la liste l1.

    J'ai l'impression qu'en fait, quand je fais "concat:=l1", il me met dans concat la liste l1 originale... sans y avoir rajouter quoique ce soit...
    Je me demande si le nil de l1 est bien supprimé...

  4. #4
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Attention, l1 ne soit pas être modifiée car c'est la tête de la liste. Il faut bien que le dernier pointeur suivant de l1 pointe sur l2, ce qui apparemment est bien effectué par ta fonction. A la limite ca sert à rien d'utiliser une fonction, puisque l1 n'a pas changé, juste une procédure suffit (enfin conceptuellement).

    Peux-tu nous donner tout le code si il n'est pas trop long ? Sinon juste la fonction appelante et la déclaration des variables.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  5. #5
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    Bon, ça avance...
    Plusieurs choses :
    * je trouve aussi qu'une procédure serait mieux... mais c'est un devoir que j'ai à faire, et donc je fais ce qu'on me demande... :-S
    * après encore des recherches, j'ai trouvé autre chose : en fait, je ne m'en étais pas rendu compte, mais il y avait un problème avec l1...
    C'est assez long à expliquer, et moi-même j'ai pas tout compris, mais en fait, en résumé :
    1. quand j'affiche l1 et l2 avant d'appeler concat, tout va bien
    2. ensuite, je fais : l3:=concat(l1,l2);
    et là, c'est magique : l1 est modifiée... en la concaténation de l1 et l2 !!
    l2 n'est pas modifiée... et l3... ça correspond à la concaténation (tenez vous bien) de la dernière cellule de l1 et de tout l2...
    Un truc auquel je pense seulement maintenant : j'ai l1 et l2 en variables globales dans le programme... et l1 et l2 en arguments dans la fonction... et j'ai bien peur que dans la fonction, ça ne soit pas considéré comme des variables locales...

    Je vais voir ça, je reviens

  6. #6
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Normalement, les arguments d'une procédure sont prioritaires sur les variables globales (enfin je crois). essaye en les renommant, on sait jamais !
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  7. #7
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    Bon, je comprends plus grand chose...
    Je vais mettre tout le code qui importe.
    Les noms des variables sont différents, j'avais simplifié en espérant que ça suffirait, mais bon...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
     
    Program DH2EXO2;
    Uses CRT;
    Type
        mot=array[0..21] of integer;
        liste_mots=^doublet;
        doublet=record
                      info:mot;
                      suiv:liste_mots
        end;
        tableau_de_liste_mots=array[0..100] of liste_mots;
    Var
       u,x,y,w:mot;
       l1,l2,l3,l4,liste,sommet:liste_mots;
     
     
    {*********************************************************************}
    {***   Procedure d'affichage d'un mot   ***}
    Procedure disp_mot(u:mot);
    var
       i:integer;
    begin
         for i:=1 to u[0] do
             write(u[i],' ');
         writeln;
    end;
    {*********************************************************************}
     
    {*********************************************************************}
    {***   Procedure d'affichage d'une liste de mots   ***}
    procedure disp_list(l:liste_mots);
    var
       i:integer;
    begin
         i:=1;
         while (l <> nil) do
               begin
                    write('Mot nø',i,' : ');
                    disp_mot(l^.info);
                    i:=i+1;
                    l:=l^.suiv;
               end;
    end;
    {*********************************************************************}
     
     
    {*********************************************************************}
    {***   Fonction concat   ***}
    Function concat(l1,l2:liste_mots):liste_mots;
    var
       la,lb,l:liste_mots;
    begin
         la:=l1;
         lb:=l2;
         l:=la;
         while (l^.suiv <> nil) do
               l:=l^.suiv;
         l^.suiv:=lb;
         concat:=l;
    end;
    {*********************************************************************}
     
     
    begin
         clrscr;
         {***   Test est_bien_forme   ***}
         u[0]:=5;
         u[1]:=1;
         u[2]:=1;
         u[3]:=-1;
         u[4]:=-1;
         u[5]:=1;
         x[0]:=5;
         x[1]:=1;
         x[2]:=1;
         x[3]:=-1;
         x[4]:=-1;
         x[5]:=-1;
         y[0]:=5;
         y[1]:=1;
         y[2]:=-1;
         y[3]:=1;
         y[4]:=-1;
         y[5]:=-1;
         construire(x,y,w);
         {***   La procédure construire construit le mot w à partir de x et y tel que : w=(x[0]+y[0],1,x[1],...,x[x[0]],y[1],...,y[y[0]])  ***}
         {***   A noter que la composante d'indice 0 d'un mot contient sa longueur   ***}
         {***   on construit une liste avec les mots x,y et w   ***}
         new(liste);
         liste^.info:=w;
         liste^.suiv:=nil;
         sommet:=liste;
         new(liste);
         liste^.info:=y;
         liste^.suiv:=sommet;
         sommet:=liste;
         new(liste);
         liste^.info:=x;
         liste^.suiv:=sommet;
         {***   liste est construite   ***}
         disp_list(liste);
         {***   Test concat   ***}
         {***   on construit l1 et l2   ***}
         writeln;
         writeln('***************** Test concat ***');
         l1:=liste;
         write('l1 : ');
         disp_list(l1);
         new(l2);
         l2^.info:=w;
         l2^.suiv:=nil;
         sommet:=l2;
         new(l2);
         l2^.info:=y;
         l2^.suiv:=sommet;
         writeln;
         write('l2 : ');
         disp_list(l2);
         {*** l1 et l2 sont construites   ***}
         writeln;
         writeln('Après appel de concat...');
         l3:=concat(l1,l2);
         writeln;
         writeln('l1 :');
         disp_list(l1);
         writeln;
         writeln('l2 :');
         disp_list(l2);
         writeln;
         writeln('l3 :');
         disp_list(l3);
         {writeln;
         write('l3 : ');
         disp_list(l3);
         writeln('Longueur de la liste concatenee : ',longueur(l3));
         {***   Fin test concat   ***}
         readkey;
    end.

    Voila...

  8. #8
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    A noter que renommer l1 et l2 dans la déclaration de la fonction concat ne change rien...

  9. #9
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    C'est normal, il faut retourner l1 dans concat...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Function concat(l1,l2:liste_mots):liste_mots;
    var
       la,lb,l:liste_mots;
    begin
         la:=l1;
         lb:=l2;
         l:=la;
         while (l^.suiv <> nil) do
               l:=l^.suiv;
         l^.suiv:=lb;
         concat:=l1;
    end;
    Si tu renvoies l tu renvoies la fin de la liste l3. Note qu'à la fin les listes l1 et l3 sont identiques... Si tu veux pas que l1 soit modifiée, il faut la dupliquer pour chaque case...
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  10. #10
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    Oui oui, il faut retourner l1 dans concat, j'ai juste fait un test en renvoyant l et j'ai oublié de modifier après...
    Par contre oui, du coup, j'ai l1 = l3 = la liste concaténée... et l2 qui ne change pas.
    Mais j'ai encore le problème de l1 qui est modifiée...
    Je crois que je vais me taper une procédure de sauvegarde de ma liste...


    Merci de ton aide en tout cas
    A bientôt !

  11. #11
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    N'oublies pas qu'il faut dupliquer aussi l2. Le principe est simple, il faut faire des new à chaque fois que tu avances dans la liste l1 ou l2, et copier la valeur de chaque case
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  12. #12
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    Je viens de commencer mais j'ai déjà une question...
    Je fais un truc ds ce style là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    while (l <> nil) do
       begin
          new(lbis);
          lbis^.info:=l^.info;
          lbis^.suiv:={###   je dois mettre quoi ici ?!   ###};
       end;
    Je peux pas y mettre l^.suiv, parce que sinon ma nouvelle liste va pointer sur des éléments de l'ancienne...

  13. #13
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Allez je suis sympa aujourd'hui :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    function duplicate(liste:liste_mots) : liste_mots;
    var newListe, l, newl: liste_mots;
    begin
      l := liste;
      new(newl);
      newl^.info := l^.info;
      newListe := newl;
      l := l^.suiv;
      while (l <> nil) do
      begin
        new(newl^.suiv);
        newl^.suiv^.info:=l^.info;
        newl := newl^.suiv;
        l := l^.suiv;
      end;
      duplicate := newListe;
    end;
    On crée un premier élément dans la nouvelle liste avec le premier élément de l'ancienne, car on a besoin de garder un pointeur vers la tête de la liste (ici la variable newListe). Ensuite on lance la boucle de copie : on crée la cellule suivante, on y assigne les données infos, puis on se place dessus. Normalement c'est bon, mais j'ai pas testé
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  14. #14
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 30
    Points : 12
    Points
    12
    Par défaut
    Merci beaucoup, ça marche très bien
    A un détail près : tu as oublié de mettre le nil à la fin de la liste copie.

    Voici la fonction avec la petite correction
    (j'ai modifié les noms de certaines variables pour que ça soit plus explicite )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    Function backup(liste:liste_mots):liste_mots;
    var
       tete_nouvelle,l_parcours,newl:liste_mots;
    begin
         l_parcours:=liste;
         new(newl);
         newl^.info:=l_parcours^.info;
         tete_nouvelle:=newl;
         l_parcours:=l_parcours^.suiv;
         while (l_parcours <> nil) do
               begin
                    new(newl^.suiv);
                    newl^.suiv^.info:=l_parcours^.info;
                    newl:=newl^.suiv;
                    l_parcours:=l_parcours^.suiv;
               end;
         newl^.suiv:=nil;
         backup:=tete_nouvelle;
    end;
    Merci bcp en tout cas !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. concaténer deux listes
    Par marcounet1312 dans le forum C
    Réponses: 8
    Dernier message: 18/09/2010, 17h49
  2. la concaténation de deux listes chainées
    Par hindou90 dans le forum C
    Réponses: 10
    Dernier message: 19/02/2010, 09h20
  3. Concaténer deux liste déroulante en une seule
    Par jules_diedhiou dans le forum Langage
    Réponses: 8
    Dernier message: 12/05/2009, 14h45
  4. Concaténer deux Listes
    Par guilopouloos dans le forum Langage
    Réponses: 4
    Dernier message: 04/11/2008, 15h01
  5. Concaténer deux listes déroulantes dans un champs texte en direct
    Par arnaudperfect dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 11/12/2007, 17h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo