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

avec Java Discussion :

Liste chainée d'entier et plateau [Débutant(e)]


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Juin 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gestionnaire de parc micro-informatique

    Informations forums :
    Inscription : Juin 2015
    Messages : 4
    Par défaut Liste chainée d'entier et plateau
    Bonjour,

    Voila pour mon examen je dois produire un programme qui doit crée une liste chainée d'entiers fournis par l'utilisateur et retourné le nombre de plateau contenus dans la liste.

    j'ai créé une classe récursive pour créé ma liste, mais j'ai un problème dans mon programme principal, je récupère une erreur et je ne trouve pas pourquoi.

    voici le code de ma classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class NOMBRE
    	{int  info;
    	NOMBRE suivant;
     
    	NOMBRE(){info=0; suivant=null;}
     
    	NOMBRE(int t, NOMBRE T)
    		{info = t;
    		suivant = T;		
    		}
     
    	public NOMBRE creerNOMBRE (int t, NOMBRE T)
    		{return new NOMBRE(t,T);}	
    }
    et mon main:

    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
    public class creerliste
    {public static void main(String [] args)
    	{	char c;
    		NOMBRE tete=new NOMBRE(0,null);
    		NOMBRE temp,temp1,temp2;
    		int n, k=1;
     
    		System.out.print(" Voulez vous saisir un nombre ? ");
    		c = Lire.c();
    		temp1 = tete;
    		temp2 = tete;
    		while (c=='O')
    			{System.out.print("Donner le nombre entier de la cellule "+k+" : ");
    			n = Lire.i();
    			temp1 = temp1.creerNOMBRE(n,null);
    			temp2.suivant = temp1;
    			temp2 = temp1;
    			System.out.print("voulez vous saisir un autre nombre ? ");
    			c = Lire.c();
    			k = k+1;
    		}
    		System.out.println("La liste contient ; ");
    		afficher(tete);
     
    		plateau(tete);
     
    		afficher(tete);
     
    	}
     
    	public static void afficher(NOMBRE T)
    	{NOMBRE aux;
    		aux = T;
    		while (aux.suivant != null)
    			{aux = aux.suivant;
    				System.out.println(aux.info);}
     
    	}
    	public static void plateau(NOMBRE T)
    	{NOMBRE aux , preced , temp;
                 preced = T;
                 aux = T;
                 aux = aux.suivant;
     
                 while(aux.suivant != null) 
                   {preced = aux;
     
                 while(aux.info != aux.suivant.info) 
                        {temp = preced.suivant;
                         preced.suivant = temp.suivant;}
     
                    aux = aux.suivant;}
    				}
     
    }
    je récupère l'erreur : Exception in thread "main" java.lang.NullPointerException
    Quelqu'un pourrai m'aider à résoudre mon soucis?

    merci d'avance.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Ajoute à ta classe NOMBRE la méthode suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @Override
    public String toString() {
        return "["+info+","+suivant+"]";
    }
    Puis modifie la boucle qui plante :

    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
    public static void plateau(NOMBRE T) {
    		NOMBRE aux, preced, temp;
    		preced = T;
    		aux = T;
    		aux = aux.suivant;
     
    		while (aux.suivant != null) {
    			preced = aux;
     
    			while (aux.info != aux.suivant.info) {
    				temp = preced.suivant;
    				preced.suivant = temp.suivant;
    				System.out.println(T);
    			}
     
    			aux = aux.suivant;
    		}
    	}
    Tu vas voir évoluer ta liste chainée : que constates-tu ?

    Indices pour résoudre le problème :

    On peut écrire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    preced = aux;
     
    while (aux.info != aux.suivant.info) {
        temp = preced.suivant;
        preced.suivant = temp.suivant;
        System.out.println(T);
    }
    comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //preced = aux;
     
    while (aux.info != aux.suivant.info) {
        temp = aux.suivant; // on prend le suivant (toujours celui de aux)
        aux.suivant = temp.suivant; 
        System.out.println(T);
    }
    (rien ne modifie la valeur dans preced)

    soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //preced = aux;
     
    while (aux.info != aux.suivant.info) {
        // temp = aux.suivant; 
        aux.suivant = aux.suivant.suivant; // le suivant de aux devient le suivant de son suivant (donc, au fur et à mesure, le suivant du suivant du suivant, etc. Le dernier suivant étant null, aux.suivant finit par être null (et donc aux.suivant.info cause une NullPointerException)
        System.out.println(T);
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Quelques remarques additionnelles:

    La classe devrait s'appeler Nombre et non pas NOMBRE. Les noms de classes sont écrit en UpperCamelCase et non pas en UPPERCASE
    Ta méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	public NOMBRE creerNOMBRE (int t, NOMBRE T)
    		{return new NOMBRE(t,T);}
    devrait soit être statique soit être carrément supprimée. Elle ne fait qu'appeler le constructeur, l'appelant en est capable. C'est une méthode juste inutile qui rends ce code confus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    		temp1 = tete;
    		temp2 = tete;
    		while (c=='O')
    			{System.out.print("Donner le nombre entier de la cellule "+k+" : ");
    			n = Lire.i();
    			temp1 = temp1.creerNOMBRE(n,null);
    			temp2.suivant = temp1;
    			temp2 = temp1;
    			System.out.print("voulez vous saisir un autre nombre ? ");
    			c = Lire.c();
    			k = k+1;
    		}
    Aussi, ta tête à 0, à moins que ça fasse partie de l'exercice, ça m'a l'air d'un emplatre pour ne pas gérer correctement le premier élément . Il serait bien plus facile à lire comme ceci

    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
    		tete = null;
    		temp = tete;
    		while (c=='O')
    			{
    			System.out.print("Donner le nombre entier de la cellule "+k+" : ");
    			n = Lire.i();
    			if (tete ==null){
    				tete = new Nombre(n,null);
    				temp = tete;
    			} else {
    				temp.suivant = new Nombre(n,null);
    				temp = temp..suivant;
                            }
    			System.out.print("voulez vous saisir un autre nombre ? ");
    			c = Lire.c();
    			k = k+1;
    		}

  4. #4
    Membre à l'essai
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Juin 2015
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gestionnaire de parc micro-informatique

    Informations forums :
    Inscription : Juin 2015
    Messages : 4
    Par défaut
    Merci a tout les deux,

    @joel.drigo , j'ai vu que l'évolution de ma chaine se terminait irrémédiablement dans une valeur "null", j'ai donc modifier ma classe avec un break:

    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
    public static void plateau(Nombre T)
    	{Nombre aux , temp , preced;
    	         aux=T;
                 preced=T;             
                 aux=aux.suivant;
     
                 while(aux.suivant!=null) 
                   {preced=aux;
    			    while(aux.info==aux.suivant.info) 
                        {temp=preced.suivant;
                         preced.suivant=temp.suivant;
    					 if(aux.suivant==null) break;}
    				if(aux.suivant!=null) aux=aux.suivant;
                       else break;				
     
                   System.out.println(T);}}
     
     
    }
    Par contre cela me donne tout les entiers differents et non pas ceux qui sont dédoublé . j'ai essayé de rajoute une condition de comptage qui fini irrémédiablement par une infinite loop.

    @tchize_ , merci pour tes conseils afin d' avoir un code plus lisible, j'ai modifier en consequence. Par contre si je suis ton code sur le 2eme point, celui ci ne prend pas en compte la premiere entrée, il apparait bien dans le retour du System.out.println(T); , mais n'apparait pas dans l'execution du afficher(tete);.

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    parceque ton afficher saute le premier element a chaque fois

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gathrog Voir le message
    Merci a tout les deux,

    @joel.drigo , j'ai vu que l'évolution de ma chaine se terminait irrémédiablement dans une valeur "null", j'ai donc modifier ma classe avec un break:

    [...]

    Par contre cela me donne tout les entiers differents et non pas ceux qui sont dédoublé . j'ai essayé de rajoute une condition de comptage qui fini irrémédiablement par une infinite loop.
    Normal, si tu traites bien des suites de "Nombre" telles que leurs "info" soit égaux, tu ne traites pas particulièrement ceux tels qu'ils soient différents (ils sont justent traités comme une série de 1 Nombre. Le while(aux.info==aux.suivant.info) fait donc le traitement pour les séries de doublons, mais il faudrait une structure du type if(aux.info==aux.suivant.info) {} else ... pour qu'on puisse traiter les autres différement.

    Si c'est cette dernière que tu voudrais obtenir, en gros, l'algo devrait être :
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    courant = tête
    tant que courant!=null et courant.suivant!=null
        si courant.suivant.info==courant.info alors
           tant courant.suivant!=null et courant.suivant.info==courant.info 
               supprimer courant.suivant (courant.suivant=courant.suivant.suivant)
           fin tant que
        sinon
           supprimer courant (ce qui oblige d'avoir le précédent : si courant==tête alors tête=courant.suivant sinon precedent.suivant=courant.suivant
        fin si
        si courant!=null alors
            courant=courant.suivant
        fin si
    fin tant que

    Ce qui complique l'algo c'est que tu modifies la liste d'origine. Est-ce bien necéssaire ? L'algo en créant une nouvelle liste serait plus simple :

    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
    nouvelle=null
    nouvelletete=null
    courant=tete
    tant que courant!=null 
       si courant.suivant!=null et courant.suivant.info==courant.info
          si nouvelle==null alors
             nouvelletete=new Nombre(courant.info,null)
             nouvelle=nouvelletete
          sinon
             nouvelle.suivant=new Nombre(courant.info,null)
             nouvelle=nouvelle.suivant
          fin si
          // on va jusqu'au dernier du plateau (on pourrait aller jusqu'au suivant de ce dernier, mais c'est plus simple de faire comme ça et de laisser l'itération suivante faire)
          tant que courant!=null et courant.suivant!=null et courant.suivant.info==courant.info 
              courant=courant.suivant
          fin tant que
      sinon
         courant=courant.suivant
      fin si
    fin tant que
    A noter que s'il est nécessaire de modifier la liste d'origine, le fait de la passer en argument pose un problème : si la tête n'est pas un doublon, on devrait la supprimer de la liste, or c'est impossible par cette façon (passer un paramètre).

    On pourrait faire ça de manière plus simple en ayant une classe de liste chainée plus riche, avec des méthodes de base (tout problème est toujours plus simple découpé en sous-problème). Par exemple, un pour obtenir la fin, une pour obtenir le prochain suivant dont info est différent du courant.ou le prochain qui est suivi d'un doublon.

    Par ailleurs, tu pourrais simplifier ton code, ça te faciliterait la mise au point : élimine les lignes de code inutile.

    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
    public static void plateau(Nombre tete) {
         Nombre aux , temp , preced;
     
         // aux=tete; // inutile : jusqu'à la prochaine affectation (1) de aux, tu ne fais rien avec aux
         preced=tete; // inutile aussi : jusqu'à la prochaine affectation (2) de aux, tu ne fais rien avec preced             
         aux = tete.suivant // aux=aux.suivant; // (1)
         // ATTENTION : tu ne compares jamais le 1er et le deuxième, puisque tu commences ta boucle de test à partir de tete.suivant 
     
         while(aux.suivant!=null) { // si la liste ne contient qu'un seul élément on n'entre pas dans la boucle, donc forcément tu auras un élément qui n'est pas doublé
              preced=aux; //(2) 
    	  while(aux.info==aux.suivant.info) {
                   temp=preced.suivant;
                   preced.suivant=temp.suivant;
    	       if ( aux.suivant==null ) break;
              }
    	  if ( aux.suivant!=null ) aux=aux.suivant; 
              else break; 	
     
        }
        System.out.println(T);
     
    }
    Déjà, tu pourrais te passer de break, en mettant la condition dans le while :

    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
    public static void plateau(Nombre tete) {
         Nombre aux , temp , preced;
     
         // aux=tete; // inutile : jusqu'à la prochaine affectation (1) de aux, tu ne fais rien avec aux
         preced=tete; // inutile aussi, en l'état du code : jusqu'à la prochaine affectation (2) de aux, tu ne fais rien avec preced             
         aux = tete.suivant; // aux=aux.suivant; // (1)
         // ATTENTION : tu ne compares jamais le 1er et le deuxième, puisque tu commences ta boucle de test à partir de tete.suivant
     
         while(aux!=null && aux.suivant!=null) { // si la liste ne contient qu'un seul élément on n'entre pas dans la boucle, donc forcément tu auras un élément qui n'est pas doublé
              preced=aux; //(2) 
    	  while(aux.suivant!=null && aux.info==aux.suivant.info) { // aux ne peut être null (while précédent)
                   temp=preced.suivant;
                   preced.suivant=temp.suivant;
              }
        }
        System.out.println(T);
     
    }
    Ensuite, la notion de précédent devrait en principe se gérer en fin d'itération (le précédent pour l'itération suivant est le courant).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. liste chainée d'entier
    Par ka123tn dans le forum Débuter
    Réponses: 2
    Dernier message: 11/01/2009, 23h53
  2. Bibliothèque de listes chainées
    Par gege2061 dans le forum C
    Réponses: 29
    Dernier message: 17/12/2004, 20h15
  3. copie de liste chainée
    Par tomsoyer dans le forum C++
    Réponses: 15
    Dernier message: 31/08/2004, 18h20
  4. Trie liste chaine
    Par Congru dans le forum C
    Réponses: 2
    Dernier message: 30/03/2004, 19h05
  5. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25

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