Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1420 connectés 

  FORUM HardWare.fr
  Programmation
  Ada

  Rangement d'une liste

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Rangement d'une liste

n°1890555
dj_titeuf
Posté le 02-06-2009 à 19:47:43  profilanswer
 

Bonsoir,
 
C'est encore moi, avec une nouvelle fois un problème sur les listes. J'explique mon sujet. Je cherche à écrire un programme qui range des valeurs saisies par un utilisateur au fur et à mesure dans une liste chaînée. Les valeurs négatives sont rangées en début de liste, et les valeurs positives sont rangées en fin de liste; la valeur 0 n'est pas rangée dans la liste, la saisie se termine quand l'utilisateur rentre 0.
 
Par exemple:
 
Si l'utilisateur fournit successivement les valeurs 4, -5, 8, 2, -3, -9, 1, 0, on cherche à obtenir l'affichage suivant:
 
"La liste contient les valeurs suivantes: -9 -3 -5 4 8 2 1."
 
Pour l'instant, voici ce que j'ai fait (je n'ai pas encore fait la procédure de saisie, il faut d'abord que le reste fonctionne, c'est plus important à mon avis):
 

Code :
  1. with Ada.Text_IO, Ada.Integer_Text_IO;
  2. use Ada.Text_IO, Ada.Integer_Text_IO;
  3. procedure Prog is
  4.  
  5.    -- Déclaration des types et sous-types
  6.  
  7.    subtype Entiers is Integer range -50..50;
  8.  
  9.    type Element;
  10.  
  11.    type Liste is access Element;
  12.  
  13.    type Element is record
  14.      
  15.       Valeur: Entiers;
  16.       Suivant: Liste;
  17.      
  18.    end record;
  19.  
  20.    -- Sous-programme qui range une valeur donnée dans une liste: les élements négatifs à gauche, les positifs à droite
  21.  
  22.    procedure Ranger_Dans_Liste (Ma_Valeur: in Entiers; Ma_Liste: in out Liste) is
  23.      
  24.       Aux: Liste := Ma_Liste;
  25.      
  26.    begin
  27.      
  28.       if Ma_Liste = null then
  29.        
  30.          Ma_Liste := new Element'(Ma_Valeur,null);
  31.        
  32.       else
  33.        
  34.          if Ma_Valeur < 0 then
  35.            
  36.             if Aux.All.Valeur > 0 then
  37.              
  38.                Aux := new Element'(Ma_Valeur,Aux);
  39.              
  40.             elsif Aux.All.Valeur < 0 then
  41.              
  42.                Aux := new Element'(Ma_Valeur, Aux.All.Suivant);
  43.              
  44.             end if;
  45.            
  46.          elsif Ma_Valeur > 0 then
  47.            
  48.             if Aux.All.Valeur > 0 then
  49.              
  50.                Aux := new Element'(Ma_Valeur, Aux.All.Suivant);
  51.              
  52.             elsif Aux.All.Valeur < 0 then
  53.              
  54.                Aux := new Element'(Ma_Valeur, Aux);
  55.              
  56.             end if;
  57.            
  58.          end if;
  59.        
  60.       end if;
  61.      
  62.    end Ranger_Dans_Liste;
  63.  
  64.    -- Sous-programme d'affichage de la liste (ordre de saisie)
  65.  
  66.    procedure Afficher_Liste (Ma_Liste: in Liste) is
  67.      
  68.       Aux: Liste := Ma_Liste;
  69.  
  70.    begin
  71.      
  72.       Put("Valeurs contenues dans la liste: " );
  73.       new_line(2);
  74.      
  75.       while Aux /= null loop
  76.        
  77.          Put(Aux.All.Valeur,0);
  78.          new_line;
  79.          Aux := Aux.All.Suivant;
  80.        
  81.       end loop;
  82.      
  83.    end Afficher_Liste;
  84.  
  85.    -- Declaration du programme general
  86.  
  87.    Ma_Liste: Liste;
  88.  
  89. begin
  90.  
  91.    Ma_Liste := new Element'(-3,new Element'(-1, new Element'(4,null)));
  92.    Ranger_Dans_Liste(-2, Ma_Liste);
  93.    Afficher_Liste(Ma_Liste);
  94.  
  95. end Prog;


 
Pour une liste vide, pas de problèmes, ça fonctionne! :bounce:  
Dans le cas contraire, ça ne va plus du tout par contre: j'ai par exemple essayé de ranger une valeur négative (-2), dans une liste donnée: -3 -1 4, en vain. Voyez-vous où sont les problèmes? J'ai essayé de m'illustrer le problème, mais je ne parviens pas à voir ce qui ne va pas. Si vous avez des questions relatives à mon code, n'hésitez surtout pas! En espérant que vous pourrez me guider, merci d'avance! ;)

mood
Publicité
Posté le 02-06-2009 à 19:47:43  profilanswer
 

n°1894103
Corebreake​r
Posté le 11-06-2009 à 12:49:07  profilanswer
 

Pourquoi ne pas utiliser les conteneurs standard de Ada.Containers comme par exemple Ada.Containers.Ordered_Sets qui est triéée?
 
Bah je me doute que c'est dans un but pédagogique, alors ok.

n°1894130
Corebreake​r
Posté le 11-06-2009 à 13:51:07  profilanswer
 

Ton erreur viens du fait que ta procédure Ranger_Dans_Liste, ne parcours pas ta liste en profondeur, elle se limite à visiter le 1er ou le 2ème élement de ta liste. Il faut utiliser une boucle ou faire de ta procédure une procédure récursive.
 
A part cela, ta procédure Ranger_Dans_Liste fais trop usine-à-gaz, il y a plus simple. Tu as aussi la version procédure récursive, que je n'indique pas ici tellement elle est simple (c'est un cas d'école), je pense que tu pourras la faire facilement une fois que tu auras compris le principe de ma version ci-dessous.
 
Petite remarque: Comment aie-je pu écrire mon exemple ci-dessous? Simple l'idée est la même que la procédure Afficher_Liste.
 

Code :
  1. with Ada.Text_IO, Ada.Integer_Text_IO;
  2. use Ada.Text_IO, Ada.Integer_Text_IO;
  3. procedure Prog is
  4.  
  5.    -- Déclaration des types et sous-types
  6.  
  7.    subtype Entiers is Integer range -50..50;
  8.  
  9.    type Element;
  10.  
  11.    type Liste is access Element;
  12.  
  13.    type Element is record
  14.      
  15.       Valeur: Entiers;
  16.       Suivant: Liste;
  17.      
  18.    end record;
  19.  
  20.    -- Sous-programme qui range une valeur donnée dans une liste: les élements négatifs à gauche, les positifs à droite
  21.  
  22.    procedure Ranger_Dans_Liste (Ma_Valeur: in Entiers; Ma_Liste: in out Liste) is
  23.       type Adr_Liste is not null access all Ma_Liste;
  24.      
  25.       Res: aliased Liste := Ma_Liste;
  26.       Aux: Adr_Liste := Res'Access;
  27.      
  28.    begin
  29.      
  30.       if Ma_Liste = null then
  31.        
  32.          Ma_Liste := new Element'(Ma_Valeur,null);
  33.        
  34.       else
  35.        
  36.          while (Aux.All /= null) and (Aux.All.All.Valeur < 0) loop
  37.             Aux := Aux.All.All.Suivant'Access;
  38.        
  39.          end loop;
  40.          Aux.All := new Element'(Ma_Valeur, Aux.All);
  41.          Ma_Liste := Res;
  42.       end if;
  43.      
  44.    end Ranger_Dans_Liste;
  45.  
  46.    -- Sous-programme d'affichage de la liste (ordre de saisie)
  47.  
  48.    procedure Afficher_Liste (Ma_Liste: in Liste) is
  49.      
  50.       Aux: Liste := Ma_Liste;
  51.  
  52.    begin
  53.      
  54.       Put("Valeurs contenues dans la liste: " );
  55.       new_line(2);
  56.      
  57.       while Aux /= null loop
  58.        
  59.          Put(Aux.All.Valeur,0);
  60.          new_line;
  61.          Aux := Aux.All.Suivant;
  62.        
  63.       end loop;
  64.      
  65.    end Afficher_Liste;
  66.  
  67.    -- Declaration du programme general
  68.  
  69.    Ma_Liste: Liste;
  70.  
  71. begin
  72.  
  73.    Ma_Liste := new Element'(-3,new Element'(-1, new Element'(4,null)));
  74.    Ranger_Dans_Liste(-2, Ma_Liste);
  75.    Afficher_Liste(Ma_Liste);
  76.  
  77. end Prog;


 
Ce qui est beau ce que le nombre de comparaison est limité à la liste, nul besoin de tester la valeur de l'argument Ma_Valeur passé à la procédure Ranger_Dans_Liste. Mais j'avoue l'utilisation d'un type accès d'un accès (type Adr_Liste) est un peu limite, et propose donc une solution qui peut être pris pour de l'Ada bon marché et peut mal passer pour des puristes de l'Ada, car cette solution est plus inspirée du langage C ou du C++.
 
La meilleure solution est d'utiliser des objets et de convertir le type Liste en tagged record. La manipulation de la liste chainée gagnerai en simplicité du code et permettrait au code d'etre plus dans la philosophie Ada en évitant ce type Adr_Liste.
 
sinon une autre version tout aussi simple serait:

Code :
  1. if négatif then
  2.   mettre au début;
  3. else
  4.   aller à la fin de la liste;
  5.   mettre à la fin;
  6. end if;


 
ou

Code :
  1. Res: Liste := Ma_Liste;
  2.    Aux: Liste := Ma_Liste;
  3. begin
  4.    ( .... )
  5.    if Ma_Valeur < 0 then
  6.       Ma_Liste:= new Element'(Ma_Value, Res);
  7.    else
  8.       while Aux.All.Suivant /= null loop
  9.          Aux:= Aux.All.Suivant;
  10.       end loop;
  11.      
  12.       Aux.All.Suivant:= new Element'(Ma_Valeur, null);
  13.       Ma_Liste:= Res;
  14.    end if;
  15.    ( .... )
  16.  
  17. end;


Message édité par Corebreaker le 11-06-2009 à 14:04:23

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Ada

  Rangement d'une liste

 

Sujets relatifs
zone de listeliste déroulante et sous formulaire
Inverser une liste[C]renverser une liste chainée
Liste déroulante récalcitrante (classique ?)reporting service matrix liste ou autre
Liste déroulanteliste déroulante + tableau
Calcul longueur d'une liste à liens multiplesRecherche rapide de liste
Plus de sujets relatifs à : Rangement d'une liste


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR