LinkedList d'une classe (chercher max)

Fermé
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 - 18 mai 2013 à 09:04
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 - 24 mai 2013 à 16:57
Bonjour à tous,

C'est l'une des premières fois que je programme des listes en Java alors voilà.
J'ai une classe Couple :

class Couple {
int label;
int numero;
Couple(int label,int numero) {
this.label = label;
this.numero = numero;
}
}


Et une liste de Couple :

LinkedList<Couple> execution = new LinkedList<Couple>();


J'essaie de faire une fonction qui me renvoie la cellule de la liste qui contient le maximum en terme de Label.Je n'y arrive pas, avec les iterator, les next cela m'a l'air assez difficile...

Cordialement et merci beaucoup d'avance.
A voir également:

9 réponses

KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
18 mai 2013 à 09:56
À chaque fois que tu peux manipuler des Iterator, tu peux utiliser la boucle for each, son utilisation est bien plus simple et remplace la plupart des cas d'utilisation des Iterator qui ne servent donc quasiment jamais...

Exemple d'affichage de la liste :

for (Couple couple : execution)
     System.out.printf("label=%d, numero=%d\n", couple.label, couple.numero);
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
Modifié par Étienne9 le 18/05/2013 à 13:14
Merci beaucoup KX.
Logiquement cela est correct non ? :



 public static Couple rechercherMaximun(LinkedList<Couple> L) {
  Couple maximum = L.getFirst();
  for (Couple couple : L) {
   if (couple.label > maximum.label) {
    maximum = couple;
   }
  }
  return maximum;
 }


Merci beaeaucoup.
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
18 mai 2013 à 13:55
Oui, c'est comme ça qu'il faudrait faire.

Cependant la méthode getFirst n'est pas une méthode de manipulation de liste, elle existe dans LinkedList mais c'est un héritage de l'interface Deque. Il serait bon de te limiter à l'interface List pour rester cohérent avec ce que tu fais.

De plus, attention, car il est possible d'avoir des objets null, aussi bien pour ta liste, que pour les objets qui la compose. Il faut donc traiter tous les cas.

public static Couple maximum(List<Couple> liste)
{
    if (liste==null)
        return null;
    
    Couple max = null;
    for (Couple couple : liste)
        if (max==null || (couple!=null && couple.label > max.label))
            max = couple;
    
    return max;
}

Remarque : il est même possible d'être encore plus général, en changeant List<Couple> par Iterable<Couple>. Comme ça toutes les classes qui ont des Iterator pourront être utilisées par ta méthode, que ce soit des listes, des piles, des arbres, etc.
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
19 mai 2013 à 16:04
Salut KX,

J'ai une question, si je fais un :

while(true)

Et qu'après je mets un for each, ça plante ou pas ?
Car j'ai besoin de ça mais j'ai l'impression que c'est ça qui fait pour péter.

Cordialement.
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
19 mai 2013 à 16:10
Je ne comprends pas ce que tu veux faire. T'aurais pas un morceau de code ?

D'un point de vue général, rien ne t'empêche de mettre une boucle for dans une boucle while, de même que tu peux mettre un while dans un autre while, ou un for dans un for...

La seule restriction vu ce que tu fais, c'est que tu ne peux pas modifier ta liste pendant que tu fais ton parcours, parce que les itérateurs seront modifiés et que ça n'aurait plus de sens d'itérer sur la liste avant modification.
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
Modifié par Étienne9 le 19/05/2013 à 16:45
En fait, là je suis dans un autre projet et j'ai des erreurs mais je ne les comprends pas :

http://img11.hostingpics.net/pics/488532Sanstitre.jpg

Je suis dans mes Fourmis mais je pense que le soucis a l'air de venir de la liste.
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
19 mai 2013 à 16:55
Comment puis-je durant mon parcours ajouter un élément s'il vous plaît ?
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
19 mai 2013 à 17:15
Le problème est bien celui que j'indiquais : "tu ne peux pas modifier ta liste pendant que tu fais ton parcours, parce que les itérateurs seront modifiés et que ça n'aurait plus de sens d'itérer sur la liste avant modification."

Tu ne peux pas ajouter un élément à ta liste pendant ton parcours. Le next n'a plus de sens puisque la liste a été modifiée. La manière de résoudre le problème dépendra de ce que tu veux faire exactement comme traitement sur ta liste (ajout à la fin, au milieu, suppressions, etc.), mais en général il faudra te servir d'une deuxième liste (temporaire).
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
19 mai 2013 à 17:21
Bah en fait c'est parce que la Reine peut pondre des oeufs et donc il peut y avoir de nouvelles Fourmis.
Alors que ça soit au début ou à la fin, à la limite je m'en moque un peu car le tout c'est que la prochaine fois que je parcours que ça y est...
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
19 mai 2013 à 17:33
Voici l'idée de base :

public void ajouter(List<Fourmi> colonie)
{
    List<Fourmi> nouvelleGeneration = new LinkedList<Fourmi>();
    
    for (Fourmi f : colonie)
    {
        if ( ??? )
            nouvelleGeneration.add(new Fourmi());
    }
    
    colonie.addAll(nouvelleGeneration);
}
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
19 mai 2013 à 17:36
Je n'ai pas bien compris. Voilà mon code actuel sachant que ajouter une Fourmi c'est PONDRE :

public void simule() {
		LinkedList<Fourmi> fourmis;
		while(true) {
			if(avecAffichage) {
				afficherTerrain();
				jeu.refresh();
			}
			/**try {
				Thread.sleep(700);
			}
			catch (InterruptedException ex) {
				Thread.currentThread().interrupt();
			}**/
			for (Nid nid : nids) {
				fourmis = nid.getFourmis();
				for (Fourmi f : fourmis) {
					if (f.getNourriture() >=1) {
						f.setNourriture(f.getNourriture()-1);
					}
					f.mourirDeVieillesse(1);
					f.mourirDeFaim();
					if (!f.enVie()) {
						if (!(f.dansSonNid())) {
							TerrainFranchissable tf = (TerrainFranchissable) tab[f.getX()][f.getY()];
							tf.supprimerOccupant();
						}
						nid.removeFourmi(f);
					}
					else {
						System.out.println("Pipi");
						if (f instanceof Reine) {
							if (f.avoirFaim()) {
								if (nid.getReserve() >= 60) {
									f.manger(60);
									nid.enleverALaReserve(60);
								}
								else {
									f.manger(nid.getReserve());
									nid.setReserve(0);
								}
							}
							else {
								Reine r = (Reine) f;
								r.pondre();
							}
						}
.................
................
................
}
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
19 mai 2013 à 18:02
Quand tu ponds un oeuf tu ajoutes une ou plusieurs fourmis, c'est ce que j'avais appelé la "nouvelle génération", on ajoutes temporairement les nouvelles fourmis dans cette liste, et on ne les ajoutes à ton nid qu'une fois la boucle terminée.

Remarque : tu vas avoir le même problème avec ton removeFourmi, ça ne fonctionnera pas car tu ne peux pas supprimer des éléments de ta liste.

Du coup il serait plus intéressant de mettre dans la deuxième liste toutes les fourmis à garder, c'est à dire les fourmis en vies, ainsi que les nouvelles fourmis qui viennent d'être pondues.

for (Nid nid : nids)
{
    List<Fourmi> vivantes = new LinkedList<Fourmi>();
    
    for (Fourmi f : nid.getFourmis())
    {
        if (f.getNourriture() >= 1)
            f.setNourriture(f.getNourriture()-1);
        
        f.mourirDeVieillesse(1);
        f.mourirDeFaim();
        
        if (f.enVie())
        {
            vivantes.add(f);
            
            System.out.println("Pipi");
            
            if (f instanceof Reine)
            {
                Reine r = (Reine) f;
                
                if (r.avoirFaim())
                {
                    if (nid.getReserve() >= 60)
                    {
                        r.manger(60);
                        nid.enleverALaReserve(60);
                    }
                    else
                    {
                        r.manger(nid.getReserve());
                        nid.setReserve(0);
                    }
                }
                else
                {
                    //r.pondre();
                    vivantes.add(new Fourmi());
                }
            }
        }
        else // fourmi morte
        {
            if (!f.dansSonNid()) 
            {
                TerrainFranchissable tf = (TerrainFranchissable) tab[f.getX()][f.getY()];
                tf.supprimerOccupant();
            }
        }                
    }
    
    nid.setFourmis(vivantes);
}
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
19 mai 2013 à 18:53
Comment savoir si une LinkedList est vide s'il vous plaît ?
En fait j'ai procédé autrement, j'ai fait deux listes, une ajouter et une supprimer.
Ça revient presque à ce que vous faites.
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
19 mai 2013 à 19:39
Toutes les listes, piles, arbres etc. partagent une interface commune : Collection
Il faut que tu apprennes les méthodes qui la contienne car tu en auras souvent besoin.

En particulier tu as la méthode isEmpty() qui permet de savoir si une Collection est vide.
Attention : n'utilises pas la méthode size()==0, car Java serait obligé de parcourir toute la liste pour compter le nombre total de fourmis avant de pouvoir dire s'il est égal à 0 ou non.
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
20 mai 2013 à 11:47
Bonjour,

En fait, dans ma simulation je ne peux pas supprimer un élément en même temps que je parcours ma liste Fourmis.
Conclusion : j'ai deux listes provisoires, une qui s'appelle Ajouter et une qui s'appelle Supprimer. Les deux sont de type <Fourmi>.
Dans la Fourmi il y a donc comme vous le savez
- Ouvrière
- Guerrière
et
-Reine.
Le problème est que, quand une guerrière combat il faut qu'elle ajoute la fourmi dans la liste Supprimer
Le soucis c'est que ça peut être autre chose qu'une fourmi et quand je fais des castes je me retrouve avec des pointeurs sur du NULL.
En effet, si je caste un EtreVivant en Fourmi, apparemment ça perd toutes les données...

Cordialement et merci beaucoup d'avance.
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
20 mai 2013 à 18:21
"quand je fais des castes je me retrouve avec des pointeurs sur du NULL.
En effet, si je caste un EtreVivant en Fourmi, apparemment ça perd toutes les données"

Non, c'est forcément une autre erreur que ça.

"quand une guerrière combat il faut qu'elle ajoute la fourmi dans la liste Supprimer
Le soucis c'est que ça peut être autre chose qu'une fourmi "

Pas besoin de cast pour ça, il suffit de tester le type avant pour vérifier que c'est bien une fourmi.

Comme d'habitude tu n'as pas donné ton code alors je suis obligé de deviner :

Guerriere g;
EtreVivant mort = g.combat();

if (mort instanceof Fourmi)
    supprimer.add((Fourmi) mort);

Remarque : l'utilisation d'une liste "supprimer" est maladroite. Pour ajouter la liste avec addAll ça se fait bien sur une liste, mais pour removeAll les performances sont mauvaises avec une liste. C'est pour ça que dans mon code d'avant la liste secondaire que j'utilisais contenait toutes les fourmis de la génération d'après : code #12
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
Modifié par Étienne9 le 24/05/2013 à 13:03
Bonjour,

Je viens d'obtenir encore un ConcurrentModificationException là dessus et je ne sais pas pourquoi.

Pouvez-vous m'aider s'il vous plaît ?



while(true) {
   int nouvelleNourriture = 1+(int) (Math.random()*100);
   if ((nouvelleNourriture < 50) && (nouvelleNourriture > 40)) {
    creerNourritureAleat();
    creerNourritureAleat();
    creerNourritureAleat();
    creerNourritureAleat();
    creerNourritureAleat();
   }
   if(avecAffichage) {       
    afficherTerrain();
    jeu.refresh();
   }
   try {
    Thread.sleep(100);
   }
   catch (InterruptedException ex) {
    Thread.currentThread().interrupt();
   }
   for (Nid nid : nids) {
    fourmis = nid.getFourmis();
    for (EtreVivant ev : fourmis) {
     ev.evoluer(tab,fourmisRescapes);
    }
    nid.setFourmis(fourmisRescapes);
   }
  }
 }


PS : apparemment ça vient de mon setFourmis qui change ma liste de Fourmis dans le Nid mais je ne supprime pas le nid, je modifie juste un attribut... C'est étrange non ?

Comment puis-je faire s'il vous plaît ?
Cordialement et merci beaucoup d'avance.
0
Étienne9 Messages postés 1022 Date d'inscription mardi 1 mars 2011 Statut Membre Dernière intervention 10 mai 2015 49
24 mai 2013 à 16:57
J'ai trouvé, pour la liste rescapés il faut recréer une nouvelle liste...
0