Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage Arbre n aire

    28 août 2019 à 20:30:46

    Bonjour a tous !

    Je viens vers vous, aujourd'hui car j'ai un petit problème sur ma fonction d'affichage de mon arbre n-aire. c'est un arbre personnaliser donc avant je vais vous en parler un peu :

    Voici un petit schémas qui pourra vous aider a voir la structure :

    Arbre n-aire structure

    Cette exemple sert a stocker les mot : a, avec, avant, avancer

    je ne sais pas trop quoi dire de plus car je pense que l'image est très parlante mais si vous avais des question hésitez pas .

    J'ai finalement réussi a faire la fonction de remplissage du dico, enfin je crois, et pour pouvoir passer a la l'exploitation de l'arbre j'essaye de l'afficher seulement la fonction d'affichage ce révèle être un défi de taille pour moi car en plus de géré la descente en profondeur de l'arbre je dois géré aussi ça remonté dû au mot qui peuvent ce cumuler ex :

    avance et avancement le premier est inclus dans le second et dans l'arbre le seule séparateur est le data qui deviens non null a la branche "e" de avance.

    j'ai aussi beaucoup de mal a lui dire de remonter et s’arrêter a un certain stade.

    enfin voila la fonction :

    public void Affiche(Branche e) {
    		
    		if(e.GetLettre().isEmpty()) {
    			// la lettre est vide donc on est a la racine
    			Affiche(e.GetBranche().get(0));
    		}else {
    			// la lettre n'est pas vide on est donc entrer dans le dico
    			// on reccupere la lettre pour former le mot a afficher
    			String mot = "";
    			mot += e.GetLettre();
    			int i=0;
    			// la boucle ici sert a parcourt l'ensemble des lettres d'une branche sur le schémas ex lettre v qui contient A et E
    			while(i<e.GetBranche().size()) {
    				if(e.GetData()==null) {
    					// le mot former pour le moment n'as pas de data ce n'est donc pas un mot référencer par le dico donc on passe a la branche suivante
    					Affiche(e.GetBranche().get(i));
    				}else {
    					//ici data n'est pas null donc on affiche le mot trouver
    					System.out.println(mot);
    					Afficher_mot(mot,e.GetData());
    					// il n'y a pas de réccurence donc on commence la remonter dans la lecture de l'abre
    				}
    				i++;
    			}
    			
    		}
    	}

    j'ai bien commenter normalement.

    Merci d'avance.

    PS: Si quelqu'un a besoin de plus de code comme les différentes classes ou la fonction d'ajout n'hésitez pas !

    -
    Edité par Robin Mathieu 28 août 2019 à 20:33:45

    • Partager sur Facebook
    • Partager sur Twitter
      29 août 2019 à 10:28:22

      Je voudrais surtout comprendre un peu mieux ton problème.
      Ca veut dire quoi "J'ai beaucoup de mal" : le programme plante ? tu as un résultat différent de ce que tu attends ? si oui, en quoi est-ce différent ?

      D'ores et déjà quelques remarques sur le code :

      • Respecte les conventions de nommage : les noms de variables et de méthodes commencent par une minuscule, les noms de classes par une majuscule.
        Si la méthode getBranche() renvoie une liste de branches, appelle-la plutôt getBranches() (au pluriel).

      • Le seul endroit où tu utilises getLettre() est ici :
        String mot = "";
        mot += e.GetLettre();
        Donc tu ajoutes toujours la lettre à un mot vide. Avec ça tu ne peux avoir que des mots d'une lettre.
        Si tu ne peux (veux) pas lire les lettres précédentes à partir de la branche e, il va falloir que ta méthode Affiche prenne le début du mot en argument :
        public void affiche(Branche e, String debutMot) {
            ...
            affiche(getBranche().get(i), mot);
            ...
        }
      • Cette boucle est tout indiquée pour utiliser un for plutôt qu'un while :
        int i=0;
        while(i<e.GetBranche().size()) {
            ...
            i++;
        }
        devient :
        for (int i=0; i<e.getBranche().size(); i++) {
            ...
        }
        ou encore mieux :
        for (Branche branche : e.getBranche()) {
            ...
        }
      • Je ne comprends pas bien non plus ce que tu mets dans Data. Tu ne t'en sers que pour vérifier s'il est null. Dans ce cas, il vaudrait mieux le déclarer comme boolean.
        Je crois comprendre qu'il permet de dire qu'on est à la fin d'un mot, même si la branche peut continuer comme dans l'exemple des mots "avance" et "avancement". Est-ce bien ça ? Si oui, il vaudrait mieux l'appeler isWordEnd (par exemple), parce que "Data" ça ne veut rien dire de clair dans ce contexte.
      • Partager sur Facebook
      • Partager sur Twitter
        29 août 2019 à 12:55:46

        Zachee54 tout d'abord merci pour ta réponse.

        •  pour parler de la convention des noms de variables, je vais essayer de prendre le coup de main et de rendre ça lisible pour tout le monde.
        •  Ensuite ton dernier point car avant de passer a la suite il vaut mieux éclaircir cela:

        Data est une classe de donnée liée au mot en question qui est censé se former avec la dernière lettre lu et en parcourant l'arbre jusqu’à ce point. 

        Voila comment il est dans branche:

        	/*** Attributs ***/
        	
        	private String Lettre;
        	private ArrayList<Branche> OccString;
        	private Mot_Data data;
        	
        	/*** Constructeurs ***/
        	
        	public Branche (String let) {
        		this.Lettre = let;
        		this.OccString = new ArrayList<Branche>();
        		this.data = null;
        	}

        et je te montre la classe data :

        	/*** Attributs ***/
        	
        	private String Lemme;
        	private String cgram;
        	private String genre;
        	private String nombre;
        	private boolean islem;
        	
        	/*** Constructeurs ***/
        	
        	public Mot_Data() {
        		this.Lemme = "";
        		this.cgram = "";
        		this.genre = "";
        		this.nombre = "";
        		this.islem = false;
        	}

        Donc oui il marque bien la fin d'un mot mais ne peut pas être convertis en boolean car il contient des données.

        • Voila maintenant que j'ai répondu au question correspondant au programme en lui même parlons de tes premières questions:
        Ca veut dire quoi "J'ai beaucoup de mal" : le programme plante ? tu as un résultat différent de ce que tu attends ? si oui, en quoi est-ce différent ?


        le programme ne plante pas mais n'affiche pas ce qui est attendu : (affichage de l’exécution )

        Début de Séquençage ...
        a	a	avoir	AUX			18559.22	12800.81	6350.91	2926.69	ind:pre:3s;	3	9	0	1	1	V	V	25	20	1	1	a	1	V	a	a	a	NOM,AUX,VER			1	1	avoir	1
        mot : a
        a	a	avoir	VER			13572.40	6426.49	5498.34	1669.39	ind:pre:3s;	3	9	0	1	1	V	V	25	20	1	1	a	1	V	a	a	a	NOM,AUX,VER	93	16	1	1	avoir	1
        mot : a
        a capella	akapEla	a capella	ADV			0.04	0.07	0.04	0.07		1	2	1	9	7	V CVCVCCV	VCVCVCV	0	0	6	5	a-ka-pE-la	4	V-CV-CV-CV	allepac a	alEpaka	a ca-pel-la	ADV			3.85	2.85	a-capella	2
        mot : a capella
        a cappella	akapEla	a cappella	ADV			0.04	0.07	0.04	0.07		1	2	1	10	7	V CVCCVCCV	VCVCVCV	0	0	6	5	a-ka-pE-la	4	V-CV-CV-CV	alleppac a	alEpaka	a cap-pel-la	ADV			4.6	2.85	a-cappella	2
        mot : a cappella
        a contrario	ak§tRaRjo	a contrario	ADV			0.00	0.27	0.00	0.27		1	1	1	11	9	V CVCCCVCVV	VCVCCVCYV	0	0	4	5	a-k§-tRa-Rjo	4	V-CV-CCV-CYV	oirartnoc a	ojRaRt§ka	a con-tra-rio	ADV			4.3	3.3	a-contrario	2
        mot : a contrario
        Séquençage terminée .
        
        a
        

        L'affichage se produit une fois le séquençage terminée.

        l'affichage attendu serait:

        a

        a capella

        a cappella

        a contrario

        • Enfin pour les deux point centraux que tu as évoqué j'ai recodé la fonction se matin et j'ai déjà résolu ces deux erreurs voici la nouvelle fonction:
        public void Affiche(Branche e, String mot) {
        		if(e.GetLettre().isEmpty()) {
        			Affiche(e.GetBranche().get(0),mot);
        		}else {
        			if((!e.GetBranche().isEmpty())&&(e.GetData() != null)) {
        				mot += e.GetLettre();
        				for(int i=0;i<e.GetBranche().size();i++) {
        					if(e.GetData() != null) {
        						System.out.println(mot);
        					}
        					Affiche(e.GetBranche().get(i),mot);
        				}
        				mot = mot.substring(0, mot.length()-1);
        			}
        		}
        	}

        PS : l'affichage du compilateur est bien celui lié a cette fonction.



        • Partager sur Facebook
        • Partager sur Twitter
          29 août 2019 à 15:10:36

          • Du point de vue de la conception, je me demande si tu avais vraiment l'utilité d'un arbre n-aire pour ça, et si une SortedMap<String,Data> n'aurait pas suffi.
            Si tu cherches à parcourir le dictionnaire dans l'ordre alphabétique, il suffirait d'itérer sur la SortedMap.
            Si tu cherches à avoir un accès en temps logarithmique, la classe TreeMap (qui implémente SortedMap) est parfaitement adaptée.
            Si tu cherches à gagner de l'espace mémoire, à mon avis tu y gagnes un peu mais ça n'en vaut pas la chandelle.
            Si c'est un défi technique... alors là d'accord ! :lol:

          • Je ne vois pas l'intérêt de ta première condition :
            if(e.GetLettre().isEmpty()) {
                Affiche(e.GetBranche().get(0),mot);
            Pourquoi ne parcourir que la première branche ? Ou s'il n'y en a qu'une, pourquoi ne pas la fournir directement par la classe appelante ?
            Tu obliges Affiche à s'appeler elle-même dès le premier appel, sans avoir traité aucune donnée.

          • Quelques incohérences dans tes conditions :
            if(e.GetLettre().isEmpty()) {
                ...
            } else {
                if((!e.GetBranche().isEmpty())&&(e.GetData() != null)) {
                    ...
                }
            }
            - Utilise le mot-clé "else if" plutôt que de mettre un "else" qui ne contient que un "if".
            - Inutile de tester !e.getBranche().isEmpty() puisque tu as testé l'opposé juste avant et que tu es dans le "else" ; donc à cet endroit du code c'est toujours vrai.
            - Que se passe-t-il si e.getData() == null ?... Mmh ? :-°... Rien ! Or si je comprends bien il devrait quand même se passer quelque chose, ne serait-ce qu'ajouter la lettre suivante même si elle ne termine pas un mot.
            - Ca ne sert à rien de tester e.getData() != null dans la suite du code, puisque tu es déjà à l'intérieur d'une condition qui l'a vérifié :
            if((!e.GetBranche().isEmpty())&&(e.GetData() != null)) {
                ...
                if(e.GetData() != null) {  // Toujours vrai ici
                    ...
                }
                ...
            }

            Je me demande si le résultat que tu montres est bien celui de la fonction telle que tu l'as réécrite ? Je n'ai pas l'impression.

          • Tu vas dire que je suis maniaque mais si tu n'as pas besoin de \(i\) alors cette syntaxe est plus appropriée et surtout plus lisible, y compris pour toi :
            for (Branche branche : e.getBranche()) {
                ...
                Affiche(branche, mot);
          • Cette ligne est inutile parce que les String sont des objets immuables en Java. Quand tu modifies le mot, en fait tu ne modifies pas l'objet String ; tu en crées un nouveau que tu stockes à la place de l'ancien dans la variable locale "mot". Ca n'a aucune influence à l'extérieur de la méthode, y compris sur les appels précédents et suivants. Donc remettre la variable "mot" dans son état antérieur à la fin de la méthode, c'est inutile et ça ne produit pas l'effet que tu en attendais.
            mot = mot.substring(0, mot.length()-1);

          Pour en venir au fait o_O, je ne vois pas trop la différence entre ce que tu obtiens et ce que tu voulais obtenir.

          Est-ce que le problème est qu'il t'affiche deux fois "a", une fois comme AUX et une fois comme VER ?
          Ou bien qu'il te l'affiche encore une fois après le séquençage ?
          Ou qu'il t'affiche des tas de données à côté alors que tu ne voulais que les mots tout seuls ?...

          • Partager sur Facebook
          • Partager sur Twitter
            29 août 2019 à 20:06:12

            Bon au final cette aprem j'ai trouver la soluce et la voila :

            public void Ajout(Branche e, String mot, String ligne){
            		
            		if(mot.isEmpty()) {
            			e.SetData(Triage_Data(ligne));
            		}else {
            			String first = mot.substring(0, 1);
            			mot = mot.substring(1);
            			if(e.GetLettre().isEmpty()) {
            				e.GetBranche().add(new Branche(first));
            				Ajout(e.GetBranche().get(0),mot,ligne);
            			}else {
            				int i=0;
            				while((i<e.GetBranche().size()) && (!e.GetBranche().get(i).GetLettre().equals(first))) {
            					i++;
            				}
            				
            				if(i == e.GetBranche().size()) {
            					e.GetBranche().add(new Branche(first));
            					Ajout(e.GetBranche().get(i),mot,ligne);
            				}else {
            					Ajout(e.GetBranche().get(i),mot,ligne);
            				}
            			}
            		}
            		
            	}
            	
            	public void Affiche(Branche e, String mot) {
            		if(e.GetLettre().isEmpty()) {
            			Affiche(e.GetBranche().get(0),mot);
            		}else if((!e.GetBranche().isEmpty())||(e.GetData() != null)) {
            				mot += e.GetLettre();
            				if(e.GetData() != null) {
            					System.out.println(mot);
            				}
            				for(Branche branche : e.GetBranche()) {
            					Affiche(branche,mot);
            				}
            				mot = mot.substring(0, mot.length()-1);
            		}
            	}

            et voila l'affichage du compilateur :

            a
            a capella
            a cappella
            a contrario
            a fortiori
            a giorno
            a jeun
            a l'instar
            a posteriori

            maintenant :

            • l’intérêt est pour moi un challenge technique qui me permet d'apprendre plus en profondeur un thème ici la récursivité et les arbres n-aire. mais cela fait aussi partie d'un projet plus important et qui me tiens a cœur, or je veux le coder comme ça déjà pour un soucis pratique par rapport a l'exploitation qu'il y aura après. et aussi parce que jusqu’à maintenant je ne connaissait pas SortedMap<String,Data>.
            • l’intérêt de la première condition est pour moi la seule manière de quitter la racine de l'arbre, qui ce trouve être la seul lettre au caractère vide. 

            Pour les autres point sauf le dernier merci a toi c'est effectivement plus clair. ^^

            Enfin le dernier point et pas des moindre :)

            je t'avoue que j'ai pas compris un mot, c'est justement LA phrase qui me permet de lire l'arbre ^^, elle permet d'avoir un mot a n'importe quel moment de la lecture de l'arbre en suivant le chemin de la racine jusqu'a la lettre ou on ce situe.

            même si le probleme est résolu je laisse en non résolu pour continuer de discuter de ce programme avec toi si tu es interressé .. :)

            • Partager sur Facebook
            • Partager sur Twitter
              30 août 2019 à 10:31:44

              Robin Mathieu a écrit:

              Enfin le dernier point et pas des moindre :)

              je t'avoue que j'ai pas compris un mot, c'est justement LA phrase qui me permet de lire l'arbre ^^, elle permet d'avoir un mot a n'importe quel moment de la lecture de l'arbre en suivant le chemin de la racine jusqu'a la lettre ou on ce situe.

              Essaye d'enlever la ligne en question et tu verras bien si ça change quelque chose à ton programme.

              En reprenant ton code et après plusieurs simplifications successives, voilà comment j'aurais fait :

              public void ajout(Branche e, String mot, String ligne){
                  
                  if (mot.isEmpty()) {
                      e.setData(trieData(ligne));
                  } else {
                      char first = mot.charAt(0);    // Oblige à changer aussi le type de Branche.Lettre !
                      mot = mot.substring(1);
                      
                      Branche branche;
                      if (e.getLettre() == null) {    // Si c'est le type char. Avec String, .isEmpty() était approprié
                          // Là j'ai simplifié ton code mais
                          // je ne comprends pas le principe.
                          // Pourquoi créer systématiquement une branche
                          // sous la racine alors que si ça se trouve
                          // elle existe déjà ? On peut avoir inséré
                          // précédemment un autre mot qui commence par
                          // la même lettre.
                          branche = createBranche(first, e);
                      } else {
                          branche = getBrancheOf(first, e);
                      }
                      
                      ajout(branche, mot, ligne);
                  }
                   
              }
              
              /**
               * Renvoie la sous-branche correspondant au caractère spécifié, en la
               * créant au besoin.
               * 
               * @param c       Le caractère recherché.
               * @param node    La branche mère.
               * @return        La branche fille correspondant au caractère c,
               *                éventuellement créée pour l'occasion.
               */
              private Branche getBrancheOf(char c, Branche node) {
                  for (Branche branche : node.getBranches()) {
                      if (branche.getLettre() == c) {
                          return branche;
                      }
                  }
                  
                  // La branche n'existe pas encore, il faut la créer
                  return createBranche(c, node);
              }
              
              /**
               * Crée une sous-branche.
               *
               * @param c        Le caractère contenu dans la sous-branche.
               * @param node    La branche mère.
               * @return        La nouvelle branche ajoutée à la branche mère.
               */
              private Branche createBranche(char c, Branche node) {
                  Branche branche = new Branche(c);
                  node.add(branche);
                  return branche;
              }
               
              public void affiche(Branche e, String mot) {
                  
                  // Ne pas traiter la racine
                  if (e.getLettre() == null) {    // Si c'est le type char. Avec String, .isEmpty() était approprié
                      e = e.getBranches().get(0);    // Pas terrible mais déjà mieux qu'avant
                  }
                  
                  mot += e.getLettre();
                  
                  // Afficher le mot actuel s'il est complet
                  if (e.getData() != null) {
                          System.out.println(mot);
                  }            
                  
                  // Afficher les mots dérivés de cette branche.
                  if (!e.getBranches().isEmpty()) {
                      for(Branche branche : e.getBranches()) {
                          affiche(branche, mot);
                      }
                  }
              }

              J'ai isolé deux parties répétitives dans des méthodes à part.

              Mais le plus important, c'est que j'ai changé la structure de tes boucles : certaines instructions comme mot += e.getLettre() ont été sorties du bloc dans lequel elles se trouvaient, et le dernier if a été scindé en deux conditions indépendantes l'une de l'autre. C'est vraiment cette structure du code qui était la plus importante à corriger, parce que la façon dont tu avais codé ton algorithme présentait des incohérences de ce point de vue.

              J'ai changé le type de Lettre en char plutôt que String parce que c'est plus simple, mais c'est un détail.

              Ca ne répond toujours pas à une de mes questions : s'il y a plusieurs branches juste en-dessous de la racine, comment seront-elles traitées ?
              Actuellement ton code marche parce que tous les mots de ton dico commencent par \(a\), mais si tu mets d'autres mots il ne seront pas lus.

              -
              Edité par Zachee54 30 août 2019 à 10:36:52

              • Partager sur Facebook
              • Partager sur Twitter
                30 août 2019 à 17:53:47

                Re Eh ben je te raconte pas la prise de tête et la remise en question suite a ton message ^^

                j'ai fait les test avec ton code en adaptant et ça ne m'affichais que le "a" donc ton code ne fonctionne pas correctement, ensuite je me suis dit c'est pas parce que ça marche pas qu'il a tord ... j'ai donc revérifier mon code (mis les balises réglementaire :) ) puis tester avec les coordonnées des mots lorsque la première lettre passe de "a" a "b" et ça marche très bien preuve a l'appuis :

                Début de Séquençage ...
                Séquençage terminée .
                
                aïeux
                aïkido
                aïoli
                b
                baba
                baballe
                babas
                babasse
                babel

                "Ca ne répond toujours pas à une de mes questions : s'il y a plusieurs branches juste en-dessous de la racine, comment seront-elles traitées ?"

                (Dsl je ne sais pas comment faire de citation )

                le traitement dans le code a cette question se fait ici :

                int i=0;
                while((i<e.getBranches().size()) && (!e.getBranches().get(i).getLettre().equals(first))) {
                	i++;
                }
                				
                if(i == e.getBranches().size()) {
                	e.getBranches().add(new Branche(first));
                	ajout(e.getBranches().get(i),mot,ligne);
                }else {
                	ajout(e.getBranches().get(i),mot,ligne);
                }

                le while boucle tant que la lettre a ajouter n'est pas présente dans les possibilité de celle ci 

                et donc si le compteur i est égale a la taille des possibilité ça veut dire qu'il ne l'a pas trouver donc on ajoute

                sinon il l'a trouver donc on s'y déplace.

                Ps, y a t'il un moyen de t'envoyer mon code histoire qu'on soit sur de parler de la même chose

                PS bis ^^ : j'ai effectivement vu que :

                if(e.GetLettre().isEmpty()) {
                                e.GetBranche().add(new Branche(first));
                                Ajout(e.GetBranche().get(0),mot,ligne);
                            }else {}

                ne servait a rien du tout ^^

                -
                Edité par Robin Mathieu 30 août 2019 à 18:10:18

                • Partager sur Facebook
                • Partager sur Twitter
                  2 septembre 2019 à 11:46:54

                  Zachee54 a écrit:

                  Ca ne répond toujours pas à une de mes questions : s'il y a plusieurs branches juste en-dessous de la racine, comment seront-elles traitées ?

                  Je voulais dire : comment sont-elles traitéesà le relecture ? Tu m'as répondu sur la création de l'arbre, mais là-dessus pas de problème.

                  C'est peut-être parce que je n'ai pas bien saisi la structure de tes données, mais dans ce code tu n'appelles que la première branche sous la racine :

                  if(e.GetLettre().isEmpty()) {
                      Affiche(e.GetBranche().get(0),mot);

                  et ensuite tu n'appelles que des branches en-dessous de celle-ci. Si tu n'as pas changé ce code, je ne vois pas quand les branches "soeurs" peuvent être lues.

                  Tu peux poster le code actuel ici, ça ne doit pas être trop long ?

                  • Partager sur Facebook
                  • Partager sur Twitter
                    3 septembre 2019 à 7:59:59

                    int i=0;
                    while((i<e.getBranches().size()) && (!e.getBranches().get(i).getLettre().equals(first))) {
                        i++;
                    }
                                     
                    if(i == e.getBranches().size()) {
                        e.getBranches().add(new Branche(first));
                        ajout(e.getBranches().get(i),mot,ligne);
                    }else {
                        ajout(e.getBranches().get(i),mot,ligne);
                    }

                    c'est ici que je lit les soeurs, avec la boucle while je place mon compteur i sur la bonne branche soeur a lire, puis en dessous si il est arrivé au bout de l'arraylist des soeur ca veut dire qu'il n'a pas trouver la soeur qui correspond sinon ca veut dire qu'il l'a trouver.

                    le main :

                    public class Main {
                    	public static void main(String[] args) {
                    		
                    		Dico dico = new Dico();
                    		
                    		dico.Remplir_Dico();
                    		
                    		dico.affiche(dico.getRacine(),"");
                    	}
                    }
                    

                    Dico :

                    public class Dico {
                    	
                    	/*** Attribut ***/
                    	
                    	private Branche racine;
                    	
                    	/*** Constructeur ***/
                    	
                    	public Dico() {
                    		racine = new Branche("");
                    	}
                    
                    	/*** Getters et Setters ***/
                    	
                    	public Branche getRacine() {
                    		return this.racine;
                    	}
                    	
                    	/*** Methodes ***/
                    	
                    	public void Remplir_Dico() {
                    		System.out.println("Début de Séquençage ...");
                    		int i=0;
                    		Lecture_Fichier lec = new Lecture_Fichier("Data/Lexique.tsv");
                    		
                    		//lec.getnbligne()-1
                    		while(i<20) {
                    			lec.Lecture_Ligne_i(i);
                    			String mot = trie_mot(lec.getLigne());
                    			ajout(this.racine,mot,lec.getLigne());
                    			i++;
                    		}
                    		System.out.println("Séquençage terminée .\n");
                    	}
                    	
                    	public String trie_mot(String ligne) {
                    		String tmp = "";
                    		int i=0;
                    		
                    		while((ligne.charAt(i) != '\t') && (i<ligne.length())) {
                    			tmp += ligne.charAt(i);
                    			i++;
                    		}
                    		return tmp;
                    	}
                    	
                    	public Mot_Data trie_Data(String ligne) {
                    		Mot_Data data = new Mot_Data();
                    		String tmp = "";
                    		int i=0;
                    		int cpt_tab = 0;
                    		
                    		while(i<ligne.length()) {
                    			if(ligne.charAt(i) == '\t') {
                    				cpt_tab ++;
                    				if(cpt_tab == 3) {
                    					data.setLemme(tmp);
                    				}else if(cpt_tab == 4) {
                    					data.setCgram(tmp);
                    				}else if(cpt_tab == 5) {
                    					data.setGenre(tmp);
                    				}else if(cpt_tab == 6) {
                    					data.setGenre(tmp);
                    				}else if(cpt_tab == 14) {
                    					if(tmp.equals("1")) {
                    						data.setIslem(true);
                    					}
                    				}
                    				tmp = "";
                    			}
                    			if((cpt_tab == 2) || (cpt_tab == 3) || (cpt_tab == 4) || (cpt_tab == 5) || (cpt_tab == 13)){
                    				tmp += ligne.charAt(i);
                    			}
                    			i++;
                    		}
                    		
                    		return data;
                    	}
                    	
                    	public void ajout(Branche e, String mot, String ligne){
                    		
                    		if(mot.isEmpty()) {
                    			e.setData(trie_Data(ligne));
                    		}else {
                    			String first = mot.substring(0, 1);
                    			mot = mot.substring(1);
                    			int i=0;
                    			while((i<e.getBranches().size()) && (!e.getBranches().get(i).getLettre().equals(first))) {
                    				i++;
                    			}
                    			
                    			if(i == e.getBranches().size()) {
                    				e.getBranches().add(new Branche(first));
                    				ajout(e.getBranches().get(i),mot,ligne);
                    			}else {
                    				ajout(e.getBranches().get(i),mot,ligne);
                    			}
                    		}
                    		
                    	}
                    	
                    	public void affiche(Branche e, String mot) {
                    		if(e.getLettre().isEmpty()) {
                    			affiche(e.getBranches().get(0),mot);
                    		}else if((!e.getBranches().isEmpty())||(e.getData() != null)) {
                    			mot += e.getLettre();
                    			if(e.getData() != null) {
                    				System.out.println(mot);
                    			}
                    			for(Branche branche : e.getBranches()) {
                    				affiche(branche,mot);
                    			}
                    		}
                    	}
                    	
                    	public void afficher_mot(String mot, Mot_Data data) {
                    		System.out.println("mot trouver : " + mot);
                    		System.out.println("Lemme : " + data.getLemme());
                    		System.out.println("cgram : " + data.getcgram());
                    		System.out.println("genre : " + data.getgenre());
                    		System.out.println("nombre : " + data.getgenre());
                    		System.out.println("islem : " + data.getIslem());
                    	}
                    	
                    }
                    

                    branche :

                    import java.util.ArrayList;
                    
                    public class Branche {
                    	
                    	/*** Attributs ***/
                    	
                    	private String Lettre;
                    	private ArrayList<Branche> branches;
                    	private Mot_Data data;
                    	
                    	/*** Constructeurs ***/
                    	
                    	public Branche (String let) {
                    		this.Lettre = let;
                    		this.branches = new ArrayList<Branche>();
                    		this.data = null;
                    	}
                    	
                    	/*** Getters et Setters ***/
                    	
                    	public Mot_Data getData() {
                    		return this.data;
                    	}
                    	
                    	public void setData(Mot_Data e) {
                    		this.data = e;
                    	}
                    	
                    	public ArrayList<Branche> getBranches(){
                    		return this.branches;
                    	}
                    	
                    	public String getLettre() {
                    		return this.Lettre;
                    	}
                    }
                    

                    mot_data :

                    import java.util.ArrayList;
                    
                    public class Branche {
                    	
                    	/*** Attributs ***/
                    	
                    	private String Lettre;
                    	private ArrayList<Branche> branches;
                    	private Mot_Data data;
                    	
                    	/*** Constructeurs ***/
                    	
                    	public Branche (String let) {
                    		this.Lettre = let;
                    		this.branches = new ArrayList<Branche>();
                    		this.data = null;
                    	}
                    	
                    	/*** Getters et Setters ***/
                    	
                    	public Mot_Data getData() {
                    		return this.data;
                    	}
                    	
                    	public void setData(Mot_Data e) {
                    		this.data = e;
                    	}
                    	
                    	public ArrayList<Branche> getBranches(){
                    		return this.branches;
                    	}
                    	
                    	public String getLettre() {
                    		return this.Lettre;
                    	}
                    }
                    

                    et lecture_fichier:

                    import java.io.BufferedReader;
                    import java.io.FileInputStream;
                    import java.io.InputStream;
                    import java.io.InputStreamReader;
                    
                    public class Lecture_Fichier {
                    	
                    	/*** Attributs ***/
                    	
                    	private String NomFichier;
                    	private String Ligne;
                    	private int nbligne;
                    	
                    	/*** Constructeurs ***/
                    	
                    	public Lecture_Fichier(String NomFichier){
                    		this.NomFichier = NomFichier;
                    		this.nbligne = 0;
                    		this.Ligne = "";
                    		Size();
                    		
                    	}
                    	
                    	/*** Getters et Setters ***/
                    	
                    	public long getnbligne() {
                    		return this.nbligne;
                    	}
                    	
                    	public String getLigne() {
                    		return this.Ligne;
                    	}
                    	
                    	public void setLigne(String e) {
                    		this.Ligne = e;
                    	}
                    	
                    	/*** Methodes ***/
                    	
                    	public void Lecture_Ligne_i(int i){
                    		try{
                    			int j = 0;
                    			InputStream ips=new FileInputStream(this.NomFichier); 
                    			InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                    			BufferedReader br=new BufferedReader(ipsr);
                    			while ((br.readLine())!=null){
                    				if(i==j) {
                    					this.Ligne = br.readLine();
                    				}
                    				j++;
                    			}
                    			br.close();
                    		}
                    		catch (Exception e){
                    			System.out.println(e.toString());
                    		}
                    	}
                    	
                    	public int Size(){
                    		try{
                    			InputStream ips=new FileInputStream(this.NomFichier); 
                    			InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                    			BufferedReader br=new BufferedReader(ipsr);
                    			while ((br.readLine())!=null){
                    				this.nbligne ++;
                    			}
                    			br.close();
                    		}
                    		catch (Exception e){
                    			System.out.println(e.toString());
                    		}
                    		return this.nbligne;
                    	}
                    }
                    


                    Voili voilou, 




                    • Partager sur Facebook
                    • Partager sur Twitter
                      3 septembre 2019 à 10:56:46

                      Je trouve que c'est du bon boulot pour un débutant. Tu iras loin ! :)

                      Robin Mathieu a écrit:

                      c'est ici que je lit les soeurs, avec la boucle while je place mon compteur i sur la bonne branche soeur a lire, puis en dessous si il est arrivé au bout de l'arraylist des soeur ca veut dire qu'il n'a pas trouver la soeur qui correspond sinon ca veut dire qu'il l'a trouver.

                      Là on ne se comprend vraiment pas. Je te demande comment tu fais pour relire les branches soeurs (donc dans la méthode affiche) et tu me réponds par deux fois en citant la méthode ajout.

                      Je te confirme que chez moi, le programme ne renvoie que les mots commençant par \(a\) :

                      aïeux
                      aïkido
                      aïoli

                      Si vraiment chez toi il lit les mots commençant par \(b\), explique-moi où ? (où dans la méthode ajout, évidemment)

                      Les erreurs

                      Ton code ne marche pas tel quel chez moi. Voici quelques erreurs à corriger.

                      • Dans trie_mot :
                      while((ligne.charAt(i) != '\t') && (i<ligne.length())) {

                      Tu consultes le caractère à la position i, avant même de savoir si la ligne est finie ou non. Chez moi ça renvoie une StringIndexOutOfBoundsException.
                      Il faut d'abord vérifier que tu n'as pas atteint la fin de ligne, puis lire le caractère :

                      while((i<ligne.length()) && (ligne.charAt(i) != '\t')) {
                      • Dans Lecture_ligne_i :
                      while ((br.readLine())!=null){
                          if(i==j) {
                              this.Ligne = br.readLine();

                      Avec ce code, tu ne lis pas la ligne \(i\) mais la ligne \(i+1\), parce que quand tu arrives à la ligne \(i\) tu exécutes une nouvelle fois readLine(), qui lit la ligne d'encore après. En particulier, la première ligne de ton fichier n'est jamais lue.
                      Il faudrait faire comme ça :

                      String ligne;
                      while ((ligne = br.readLine())!=null){
                          if(i==j) {
                              this.Ligne = ligne;

                      Je ne veux pas dire, mais si ton programme ne tourne pas chez moi à cause de ces deux erreurs, et que quand je les corrige il ne donne pas non plus le même résultat que toi, je me demande vraiment comment tu as fait pour l'exécuter et obtenir tous tes mots o_O

                      Les conseils

                      try{
                          InputStream ips=new FileInputStream(this.NomFichier);
                          InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                          BufferedReader br=new BufferedReader(ipsr);
                          while ((br.readLine())!=null){
                              this.nbligne ++;
                          }
                          br.close();  // Le problème est ici !
                      }
                      catch (Exception e){
                          System.out.println(e.toString());
                      }

                      Tu ne dois jamais fermer des flux comme ça. Pour deux raisons :
                      - Si une erreur survient à la lecture, le programme passe directement dans le bloc catch sans passer par br.close(). Ainsi ton fichier sera toujours ouvert et provoque une perte de mémoire.
                      - S'il y a un problème au moment de fermer ton BufferedReader, il se peut que la méthode br.close() plante sans avoir fermé l'InputStreamReader et l'InputStream, auquel ton fichier reste aussi ouvert et occupe une mémoire vive qui ne peut plus être récupérée.

                      La solution "à l'ancienne" est de fermer les flux dans un bloc finally :

                      } finally {
                          br.close();
                          ipsr.close();
                          ips.close();
                      }

                      Je te le dis parce que tu la rencontreras forcément. Mais la méthode moderne est le "try-with-resources", qui permet que les ressources soient fermées automatiquement et proprement à condition d'avoir été déclarées entre parenthèses dans le try, avant l'accolade. Dans ce cas tu n'as même plus à les fermer manuellement :

                      try (
                              InputStream ips=new FileInputStream(this.NomFichier);
                              InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                              BufferedReader br=new BufferedReader(ipsr);) {
                      	
                          while ((br.readLine())!=null){
                              this.nbligne ++;
                          }
                      }
                      catch (Exception e){
                          System.out.println(e.toString());
                      }

                      Ta classe Lecture_fichier ne sert à rien. Elle fait la même chose que BufferedReader...
                      - avec une fonctionnalité en plus : le nombre de lignes dans le fichier. Mais tu ne t'en sers jamais !
                      - avec une fonctionnalité en moins : tu ne peux pas lire plusieurs lignes d'affilée. Pour le faire, Lecture_fichier a besoin de relire le fichier depuis le début, ce qui est exécrable du point de vue des performances (pour lire 20 lignes, tu dois ouvrir le fichier 20 fois et lire 210 fois une ligne !).
                      Utilise BufferedReader directement.
                      Cerise sur le gâteau : si tu veux la numérotation des lignes, tu peux utiliser LineNumberReader, qui est une variante de BufferedReader :

                      public void Remplir_Dico() {
                          System.out.println("Début de Séquençage ...");
                          try (FileReader fileReader = new FileReader("Data/Lexique.tsv");
                                  LineNumberReader reader = new LineNumberReader(fileReader)) {
                              
                              while (reader.getLineNumber() < 20) {
                                  String ligne = reader.readLine();
                                  if (ligne != null) {
                                      String mot = trie_mot(ligne);
                                      ajout(this.racine, mot, ligne);
                                  }
                              }
                              
                          } catch (IOException e) {
                              System.out.println(e);
                          }
                          
                          System.out.println("Séquençage terminée .\n");
                      }

                      Tu utilises fréquemment while là où il faudrait utiliser un for.

                      int i = 0;
                      while (i...) {
                          ...
                          i++;
                      }

                      devrait être remplacé par :

                      for (int i=0; i...; i++) {

                      Pourquoi ?
                      D'abord parce que c'est plus lisible et que ça prend 1 ligne au lieu de 3.
                      Ensuite parce que ça réduit le scope de \(i\) à la boucle, ce qui fait que tu ne peux pas avoir de confusion si tu utilises la variable \(i\) dans plusieurs boucles au sein de la même méthode (ça t'arrivera, crois-moi ! ;)).
                      Enfin parce que while est tout simplement fait pour d'autres situations, typiquement celles où tu n'as pas besoin de compter les étapes. Faire autrement, c'est prendre l'habitude de coder mal.

                      Utilise l'opérateur switch :

                      switch(cpt_tab) {
                      case 3:
                          data.setLemme(tmp); break;
                      case 4:
                          data.setCgram(tmp); break;
                      case 5:
                          data.setGenre(tmp); break;
                      case 6:
                          data.setGenre(tmp); break;
                      case 14:
                          if(tmp.equals("1")) {
                              data.setIslem(true);
                          }
                          break;
                      }

                      C'est pareil, il est fait pour ça.

                      Pour interpréter les fins de ligne tu peux utiliser BufferedReader (on l'a vu plus haut), et pour interpréter les tabulations tu peux utiliser Scanner :

                      public Mot_Data trie_Data(String ligne) {
                          Mot_Data data = new Mot_Data();
                          Scanner scanner = new Scanner(ligne).useDelimiter("\t");
                          scanner.next();                  // Sauter la première tabulation
                          data.setLemme(scanner.next());   // Deuxième donnée
                          data.setCgram(scanner.next());   // Troisième donnée
                          data.setGenre(scanner.next());   // Quatrième donnée
                          scanner.next();                  // Sauter la cinquième

                      C'est sans doute trop lourd de faire ça jusqu'à la 14ème tabulation, alors tu peux faire une boucle pour insérer les valeurs du scanner dans une List, puis lire ensuite celles qui t'intéresse. Je te laisse faire.

                      -
                      Edité par Zachee54 3 septembre 2019 à 11:01:44

                      • Partager sur Facebook
                      • Partager sur Twitter
                        4 septembre 2019 à 18:41:46

                        Salut a toi !

                        bon alors pour commencer je vais te montrer ce que j'ai changer suite a ton message ensuite je te parlerai des différent problème rencontrer et tout a la fin je répondrai a ta question :)

                        tout d'abord pour la fonction trie mot :

                        j'ai changer la condition du while qui était effectivement plus logique comme tu me l'as marquer mais je maintiens qu'il ne m'afficher aucune erreur, je l'ai rééxécuté plusieurs pour être sur. la voila :

                        	public String trie_mot(String ligne) {
                        		String tmp = "";
                        		int i=0;
                        		
                        		while((i<ligne.length()) && (ligne.charAt(i) != '\t')) {
                        			tmp += ligne.charAt(i);
                        			i++;
                        		}
                        		return tmp;
                        	}

                        Ensuite lecture_ligne_i :

                        j'ai aussi fait les modifs que tu m'as expliquer néanmoins cela me génère une erreur qui n'existais pas avant 

                        la fonction en question :

                        public void Lecture_Ligne_i(int i){
                        		try (InputStream ips=new FileInputStream(this.NomFichier); 
                        			InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                        			BufferedReader br=new BufferedReader(ipsr);) {
                        			int j = 0;
                        			String ligne = "";
                        			while ((ligne = br.readLine())!=null){
                        				if(i==j) {
                        					this.Ligne = ligne;
                        				}
                        				j++;
                        			}
                        		}
                        		catch (Exception e){
                        			System.out.println(e.toString());
                        		}
                        	}


                        Voila l'affichage généré :

                        Début de Séquençage ...
                        Séquençage terminée .
                        
                        ?a
                        

                        en faite il n'affiche pas ce qu'il faut plutôt que créer une erreur et il y a l'apparition de ce ? bizarre que je ne m'explique pas.

                        j'ai néanmoins continuer avec la fonction trie_Data que voici :

                        	@SuppressWarnings("resource")
                        	public Mot_Data trie_Data(String ligne) {
                        		Mot_Data data = new Mot_Data();
                        		Scanner scanner = new Scanner(ligne).useDelimiter("\t");
                        		for(int i=1;i<15;i++) {
                        			switch(i) {
                        			case 3:
                        			    data.setLemme(scanner.next()); break;
                        			case 4:
                        			    data.setCgram(scanner.next()); break;
                        			case 5:
                        			    data.setGenre(scanner.next()); break;
                        			case 6:
                        			    data.setNombre(scanner.next()); break;
                        			case 14:
                        			    if(scanner.next().equals("1")) {
                        			        data.setIslem(true);
                        			    }
                        			    break;
                        			default:
                        				scanner.next();
                        				break;
                        			}
                        		}
                        		scanner.close();
                        		return data;
                        	}

                        celle ci fonctionne beaucoup mieux ^^ merci pour tes conseil cela me seras très utile.

                        Puis la fonction remplir_Dico:

                        la voici tel que tu me l'as proposer :

                        public void Remplir_Dico() {
                        	    System.out.println("Début de Séquençage ...");
                        	    try (FileReader fileReader = new FileReader("Data/Lexique.tsv");
                        	            LineNumberReader reader = new LineNumberReader(fileReader)) {
                        	         
                        	        while (reader.getLineNumber() < 20) {
                        	            String ligne = reader.readLine();
                        	            if (ligne != null) {
                        	                String mot = trie_mot(ligne);
                        	                ajout(this.racine, mot, ligne);
                        	            }
                        	        }
                        	         
                        	    } catch (IOException e) {
                        	        System.out.println(e);
                        	    }
                        	     
                        	    System.out.println("Séquençage terminée .\n");
                        	}

                        franchement j'aime bien l'idée néanmoins deux choses me pose problème :

                        • l'idée de pas avoir la taille du fichier car même si pour les essai avec 20 lignes ca ne pose pas de problème a terme l'idée est de prendre tout le fichier et donc j'aurai besoin de sa taille ...
                        • Ensuite c'est que quand je met cette méthode il me rajoute encore de nouveau caractère spéciaux regarde :
                        Début de Séquençage ...
                        Séquençage terminée .
                        
                        a
                        

                        ci dessus l’exécution du programme avec la fonction remplir_Dico modifier(les tests d'avant ne l'avait pas.)

                        Maintenant j'arrive a ta question du début ^^ :

                        alors voila la fonction avant quand tout marchais encore(époque bénis :) )

                            public void affiche(Branche e, String mot) {
                                if(e.getLettre().isEmpty()) {
                                    affiche(e.getBranches().get(0),mot);
                                }else if((!e.getBranches().isEmpty())||(e.getData() != null)) {
                                    mot += e.getLettre();
                                    if(e.getData() != null) {
                                        System.out.println(mot);
                                    }
                                    for(Branche branche : e.getBranches()) {
                                        affiche(branche,mot);
                                    }
                                }
                            }

                        sur celle ci la lecture des branches soeur ce faisait grace a cette ligne (enfin je crois, avec toute les truc bizarre qui arrive je doute de tout )

                        for(Branche branche : e.getBranches()) {
                                        affiche(branche,mot);
                                    }

                        néanmoins après les modifications apporter suite a tes conseils voici ce que j'obtiens :

                        Début de Séquençage ...
                        Séquençage terminée .
                        
                        ?a
                        

                        et lorsque j'enlève les modifications apporté a la fonction lecture_ligne i :

                        Début de Séquençage ...
                        Séquençage terminée .
                        
                        a
                        a capella
                        a cappella
                        a contrario
                        a fortiori
                        a giorno
                        a jeun
                        a l'instar
                        a posteriori
                        a priori
                        aa
                        ab absurdo
                        ab initio
                        ab ovo
                        abaca
                        abaissa
                        abaissai
                        abaissaient
                        

                        néanmoins la lecture du dictionnaire ne fonctionne plus lorsque je lis les première lettre b, je ne sais pas pourquoi j'ai du changer quelques chose entre temps et perdre cette partie (snif)

                        Important : 

                        j'aimerai beaucoup t'envoyer le lexique que j'ai histoire que tu puisse si tu en as besoin faire tes tests avec le même fichier que moi.

                        PS: la première phrase m'as beaucoup fait plaisir ^^ merci!

                        -
                        Edité par Robin Mathieu 4 septembre 2019 à 18:45:30

                        • Partager sur Facebook
                        • Partager sur Twitter
                          5 septembre 2019 à 9:27:23

                          Les caractères bizarres sont un BOM UTF8 (byte order mark). C'est un code caractéristique et facultatif sur les 3 premiers octets du fichier pour signaler qu'il est encodé en UTF8.
                          Lorsqu'on le lit en UTF8, ça correspond à un caractère invisible mais que la console Java remplace par un point d'interrogation.
                          Lorsqu'on le lit en ISO-8859-xx, ça fait 

                          Donc deux choses à faire :

                          • demander explicitement une lecture en UT8, ce qui oblige à remplacer FileReader par FileInputStream + InputStreamReader comme tu l'avais fait. FileReader ne laisse pas le choix de l'encodage.
                          • Te débarrasser du BOM. Java ne le supprime pas lui-même parce que certaines applications en ont besoin.
                            Deux solutions :
                            - effacer le BOM dans le fichier, ce qui peut se faire avec certains éditeurs de texte. Notepad++ propose par exemple une commande "Convertir en UTF8 (sans BOM)".
                            - l'effacer dans les données lues :
                            String ligne = reader.readLine().replace('\ufeff', '');

                          Robin Mathieu a écrit:

                          l'idée de pas avoir la taille du fichier car même si pour les essai avec 20 lignes ca ne pose pas de problème a terme l'idée est de prendre tout le fichier et donc j'aurai besoin de sa taille ...

                          Pourquoi tu aurais besoin de sa taille ? Il suffit de lire les lignes jusqu'à ce que tu obtiennes null.
                          String ligne = null;
                          while ((ligne = reader.readLine()) != null) {
                              String mot = trie_mot(ligne);
                              ajout(this.racine, mot, ligne);
                          }

                          Si tu veux donner un indicateur de progression en pourcentage (ce qui est déjà une fonctionnalité avancée... :-°), alors oui tu auras besoin de la taille. Mais tu peux très bien avoir une méthode qui compte les lignes du fichier plutôt que de créer une classe qui refait le travail que fait déjà LineNumberReader.

                          Robin Mathieu a écrit:

                          sur celle ci la lecture des branches soeur ce faisait grace a cette ligne (enfin je crois, avec toute les truc bizarre qui arrive je doute de tout )

                          for(Branche branche : e.getBranches()) {
                                          affiche(branche,mot);
                                      }
                          Je veux bien te croire quand tu dis que ça marchait. Mais pas avec un des codes que tu as donnés : rien de tout ça ne lit les branches soeurs.
                          La boucle for dont tu parles est placée à l'intérieur d'un else, qui n'est exécuté que si e.getLettre().isEmpty() est false, donc si on n'est pas sur la racine.
                          Il n'y a donc aucun endroit où on lit toutes les branches filles de la racine. On ne les lit qu'avec cette ligne de code, qui ne lit que la première branche :
                          affiche(e.getBranches().get(0),mot);

                          Je pose la question autrement : pourquoi diable lire seulement la première branche ?

                          Pourquoi ne pas plutôt lire systématiquement toutes les branches filles dès qu'il y en a, qu'on soit à la racine ou pas :

                          if(!e.getLettre().isEmpty()) {
                              mot += e.getLettre();
                              if(e.getData() != null) {
                                  System.out.println(mot);
                              }
                          }
                          
                          for(Branche branche : e.getBranches()) {
                              affiche(branche,mot);
                          }

                          Enfin pour le switch : c'est la traduction "propre" de ce que tu faisais avant en testant la valeur de cpt_tab. C'est bien.
                          La méthode dans son ensemble serait plus cohérente en mettant toutes les valeurs dans une List, puis en allant chercher celles qui t'intéressent à partir de leur index.
                          switch s'utilise bien quand on ne sait pas ce qu'on va avoir, ou dans quel ordre on va l'avoir. Quand tu maîtrises toute la structure des données qui arrivent, comme c'est le cas ici, c'est contre-intuitif de faire une boucle qui teste l'étape où on en est.

                          Robin Mathieu a écrit:

                          j'aimerai beaucoup t'envoyer le lexique que j'ai histoire que tu puisse si tu en as besoin faire tes tests avec le même fichier que moi.

                          Je pense que si tu postes les 20 premières lignes ici c'est raisonnable. Sinon en messagerie privée.

                          -
                          Edité par Zachee54 5 septembre 2019 à 11:49:09

                          • Partager sur Facebook
                          • Partager sur Twitter
                            5 septembre 2019 à 10:51:28

                            Enfin j'ai fait les modifs et tout fonctionne correctement c'est assez jouissif je dois bien le dire ^^

                            je te reposte le code en entier juste dico :

                            import java.io.BufferedReader;
                            import java.io.FileInputStream;
                            import java.io.IOException;
                            import java.io.InputStream;
                            import java.io.InputStreamReader;
                            import java.util.Scanner;
                            
                            public class Dico {
                            	
                            	/*** Attribut ***/
                            	
                            	private Branche racine;
                            	
                            	/*** Constructeur ***/
                            	
                            	public Dico() {
                            		racine = new Branche("");
                            	}
                            
                            	/*** Getters et Setters ***/
                            	
                            	public Branche getRacine() {
                            		return this.racine;
                            	}
                            	
                            	/*** Methodes ***/
                            	
                            	public void Remplir_Dico() {
                            	    System.out.println("Début de Séquençage ...");
                            	    try (InputStream ips=new FileInputStream("Data/Lexique_ssBom"); 
                            				InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                            				BufferedReader reader=new BufferedReader(ipsr);)  {
                            	    	String ligne = "";
                            	        while ((ligne = reader.readLine()) != null){
                            	            ligne = reader.readLine();
                            	            if (ligne != null) {
                            	                String mot = trie_mot(ligne);
                            	                ajout(this.racine, mot, ligne);
                            	            }
                            	        }
                            	    } catch (IOException e) {
                            	        System.out.println(e);
                            	    }
                            	    System.out.println("Séquençage terminée .\n");
                            	}
                            	
                            	public String trie_mot(String ligne) {
                            		String tmp = "";
                            		int i=0;
                            		while((i<ligne.length()) && (ligne.charAt(i) != '\t')) {
                            			tmp += ligne.charAt(i);
                            			i++;
                            		}
                            		return tmp;
                            	}
                            	
                            	@SuppressWarnings("resource")
                            	public Mot_Data trie_Data(String ligne) {
                            		Mot_Data data = new Mot_Data();
                            		Scanner scanner = new Scanner(ligne).useDelimiter("\t");
                            		for(int i=1;i<15;i++) {
                            			switch(i) {
                            			case 3:
                            			    data.setLemme(scanner.next()); break;
                            			case 4:
                            			    data.setCgram(scanner.next()); break;
                            			case 5:
                            			    data.setGenre(scanner.next()); break;
                            			case 6:
                            			    data.setNombre(scanner.next()); break;
                            			case 14:
                            			    if(scanner.next().equals("1")) {
                            			        data.setIslem(true);
                            			    }
                            			    break;
                            			default:
                            				scanner.next();
                            				break;
                            			}
                            		}
                            		scanner.close();
                            		return data;
                            	}
                            	
                            	public void ajout(Branche e, String mot, String ligne){
                            		
                            		if(mot.isEmpty()) {
                            			e.setData(trie_Data(ligne));
                            		}else {
                            			String first = mot.substring(0, 1);
                            			mot = mot.substring(1);
                            			int i=0;
                            			while((i<e.getBranches().size()) && (!e.getBranches().get(i).getLettre().equals(first))) {
                            				i++;
                            			}
                            			if(i == e.getBranches().size()) {
                            				e.getBranches().add(new Branche(first));
                            				ajout(e.getBranches().get(i),mot,ligne);
                            			}else {
                            				ajout(e.getBranches().get(i),mot,ligne);
                            			}
                            		}
                            	}
                            	
                                public void affiche(Branche e, String mot) {
                                	if(!e.getLettre().isEmpty()) {
                                	    mot += e.getLettre();
                                	    if(e.getData() != null) {
                                	        System.out.println(mot);
                                	    }
                                	}
                                	for(Branche branche : e.getBranches()) {
                                	    affiche(branche,mot);
                                	}
                                }
                            	
                            	public void afficher_mot(String mot, Mot_Data data) {
                            		System.out.println("mot trouver : " + mot);
                            		System.out.println("Lemme : " + data.getLemme());
                            		System.out.println("cgram : " + data.getcgram());
                            		System.out.println("genre : " + data.getgenre());
                            		System.out.println("nombre : " + data.getnombre());
                            		System.out.println("islem : " + data.getIslem());
                            	}
                            	
                            }
                            

                            j'ai aussi supprimer les classes de lecture et ecriture fichier, car effectivement je gagne un temps de fou en éxécution.

                            Du coup ce seras pas nécessaire de te faire passer le fichier. néanmpoins pour ceux qui le lirons et ou si tu cherche la source la voila :

                            http://www.lexique.org/

                            Pour terminer car le sujet ne comprenais que le problème d'affichage, je voulais te dire un grand merci pour tout ses précieux conseil et ta patience.

                            Je vais continuer avec la fonction de recherche puis la sauvegarde donc il est probable qu'un nouveau poste fasse son apparition :)

                            Merci encore a toi .

                            PS: tu avais entièrement raison pour :

                            affiche(e.getBranches().get(0),mot);

                            c'était complètement inutile ...

                            • Partager sur Facebook
                            • Partager sur Twitter
                              5 septembre 2019 à 11:48:08

                              Attention grossière erreur de ma part : je sus allé trop vite en modifiant la boucle while qui sert à lire tout le fichier.
                              while ((ligne = reader.readLine()) != null){
                                  ligne = reader.readLine();
                                  if (ligne != null) {

                              Ces deux lignes dans la boucle font la même chose que la condition while. Du coup le programme ne lit qu'une ligne sur deux !

                              J'ai corrigé ça dans mon post précédent.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                5 septembre 2019 à 22:19:21

                                a oui effectivement, je viens de remarquer du coup, par contre j'ai corriger de cette manière :

                                genre c'est trop cool le temps de compile est passer de 2heure quand j'utiliser la classe lecture_fichier et maintenant a peine plus d'une seconde (je parle du fichier au complet "142 000" mots)

                                String ligne = "";
                                	        while ((ligne = reader.readLine()) != null){
                                	            if (ligne != null) {
                                	                String mot = trie_mot(ligne);
                                	                ajout(this.racine, mot, ligne);
                                	            }
                                	        }

                                tant que j'y suis je me suis mis sur la fonction rechercher elle ressemble a ça :

                                public Mot_Data rechercher(Branche e, String mot_trouver, String mot_chercher, Mot_Data data) {
                                			if(!e.getLettre().isEmpty()) {
                                				mot_trouver += e.getLettre();
                                				if((mot_trouver.equals(mot_chercher))&&(e.getData() != null)) {
                                					data = e.getData();
                                				}
                                			}
                                			for(Branche branche : e.getBranches()){
                                				if(mot_chercher.substring(mot_trouver.length(), mot_trouver.length()+1).equals(branche.getLettre())){
                                					data = rechercher(branche,mot_trouver,mot_chercher,data);
                                				}
                                			}
                                			return data;
                                		}

                                le problème c'est qu'elle fonctionne uniquement avec les mot qui commence par la lettre "a" j'ai vraiment un soucis avec ca je crois.



                                • Partager sur Facebook
                                • Partager sur Twitter
                                  6 septembre 2019 à 11:38:53

                                  Robin Mathieu a écrit:

                                  genre c'est trop cool le temps de compile est passer de 2heure quand j'utiliser la classe lecture_fichier et maintenant a peine plus d'une seconde (je parle du fichier au complet "142 000" mots)

                                  Ah oui, tu n'avais pas précisé la taille du fichier...

                                  Si pour lire une ligne tu dois lire le fichier depuis le début, comme je te le disais la lecture des \(n\) lignes du fichier oblige à lire \(\frac{n(n+1)}{2}\) lignes en tout.
                                  Autrement dit le temps d'exécution augmente avec le carré du nombre de lignes, ce qui fait rapidement exploser le traitement.

                                  Remarque que la condition (ligne != null) est inutile parce qu'on la vérifie juste au-dessus dans la condition du while :

                                  while ((ligne = reader.readLine()) != null){
                                      if (ligne != null) {


                                  Ta fonction rechercher est pas mal.

                                  • Remplace ton substring par un charAt puisque tu cherches un seul caractère et que tu sais à quelle position il se trouve :
                                    if (mot_chercher.charAt(mot_trouver.length()).equals(branche.getLettre())) {


                                  • Remplace tes "data = ..." par des "return ...".
                                    En effet quand tu affectes la variable data, elle ne change plus de valeur jusqu'à la fin de la méthode et tu finis par la renvoyer telle quelle.
                                    C'est plus clair pour le code, et en plus ça évite de continuer à faire tourner la boucle for alors que tu as déjà trouvé ce que tu voulais.

                                  • Je ne vois pas à quoi ça sert de passer data en argument.
                                    Tu ne t'en sers jamais, sauf pour la passer en argument récursivement (mais là le serpent se mord la queue) ou pour la renvoyer telle quelle à la fin si elle n'a pas été modifiée.
                                    Mais si tu ne l'as pas modifiée, c'est que le mot n'existe pas dans cette branche et il vaudrait donc mieux renvoyer null :
                                    public Mot_Data rechercher(Branche e, String mot_trouver, String mot_chercher) {
                                        if (!e.getLettre().isEmpty()) {
                                            mot_trouver += e.getLettre();
                                            if (mot_trouver.equals(mot_chercher) && (e.getData() != null)) {
                                                return e.getData();
                                            }
                                        }
                                        for(Branche branche : e.getBranches()){
                                            if (mot_chercher.charAt(mot_trouver.length()).equals(branche.getLettre())) {
                                                return rechercher(branche, mot_trouver, mot_chercher);
                                            }
                                        }
                                    
                                        // Mot non présent dans cette branche
                                        return null;

                                  Robin Mathieu a écrit:

                                  le problème c'est qu'elle fonctionne uniquement avec les mot qui commence par la lettre "a" j'ai vraiment un soucis avec ca je crois.

                                  C'est sans doute lié à la façon dont tu appelles la méthode. Qu'est-ce que tu lui donnes comme argument "e" au lancement ?

                                  NB : Pour chacune des méthodes ajout, affiche et rechercher, tu aurais pu faire la même chose avec une boucle while et une boucle for et ça aurait sans doute été plus simple à lire (et à écrire). Un bon exercice pour améliorer ton programme !

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    6 septembre 2019 à 13:28:56

                                    Ca y est j'ai trouver pourquoi j'avais un depassement a cause de:
                                    mot_trouver.length()+1

                                    du coup j'ai fait comme ca : (tu verra que j'ai appliquer presque tout ce dont tu as parler c'est effectivement plus clair et donc plus efficace)

                                    public Mot_Data rechercher(Branche e, String mot_trouver, String mot_chercher) {
                                    			if(!e.getLettre().isEmpty()) {
                                    				mot_trouver += e.getLettre();
                                    				if((mot_trouver.equals(mot_chercher))&&(e.getData() != null)) {
                                    					return e.getData();
                                    				}
                                    			}
                                    			if(!mot_trouver.equals(mot_chercher)) {
                                    				for(Branche branche : e.getBranches()){
                                    					if(mot_chercher.substring(mot_trouver.length(), mot_trouver.length()+1).equals(branche.getLettre())){
                                    						return rechercher(branche,mot_trouver,mot_chercher);
                                    					}
                                    				}
                                    			}
                                    			return null;
                                    		}

                                    tu peut voir que pour que cela fonctionne j'ai juste rajouter :

                                    if(!mot_trouver.equals(mot_chercher)) {

                                    pour la modification avec le charAt je t'avoue que j'hesite beaucoup pour trois raisons:

                                    • Tout d'abord mes lettres sont stocker en tant que string donc faut modifier tout le programme plus une partie de la structure.(la flem :))
                                    • Ensuite si je stock en char je ne peut pas me servir du caractere vide pour la racine car un char ne tolère pas le caractère vide ni le null. Donc je dois mettre '\u0000' mais au final ça me rajoute un espace donc c'est vraiment pas terrible pour le traitement de phrase.(l'espace c'est important dans une phrase ^^)
                                    • Et enfin je vais beaucoup travailler sur les phrases bientôt donc je me demande si c'est pas mieux de tout mettre en string histoire d'avoir plus de facilité dans le traitement en évitant les conversions.

                                    Quand je dis que je vais beaucoup travailler sur les phrases c'est parce que je vais avoir un professeur particulier sur les réseaux de neurone pour y appliquer le dico que je suis entrain de faire.

                                    je te met aussi mon fichier test il est surement mal coder mais ca c'est pas grave il est vouer a disparaitre:

                                    		Dico dico = new Dico();
                                    		int exit = 0;
                                    		
                                    		Scanner sc = new Scanner(System.in);
                                    		System.out.println("Veuillez saisir un mot :");
                                    		while(exit == 0) {
                                    			String str = sc.nextLine();
                                    			switch(str) {
                                    				case "remplir":
                                    					dico.Remplir_Dico();
                                    					break;
                                    				case "afficher":
                                    					dico.affiche(dico.getRacine(), "");
                                    					break;
                                    				case "rechercher":
                                    					System.out.println("oui, Robin ?");
                                    					String str1 = sc.nextLine();
                                    					int cpt = 0;
                                    					Scanner scanner = new Scanner(str1).useDelimiter(" ");
                                    					for(int i=0;i<str1.length();i++) {
                                    						if(str1.charAt(i) == ' ') {
                                    							cpt++;
                                    						}
                                    					}
                                    					for(int i=0;i<cpt;i++) {
                                    						String mot = scanner.next();
                                    						dico.afficher_mot(mot,dico.rechercher(dico.getRacine(), "", mot));
                                    					}
                                    					break;
                                    				case "exit":
                                    					exit = 1;
                                    					break;
                                    			}
                                    		}
                                    		sc.close();
                                    	}


                                    Voili voilou merci encore pour tes conseils.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      6 septembre 2019 à 14:59:43

                                      Robin Mathieu a écrit:

                                      tu peut voir que pour que cela fonctionne j'ai juste rajouter :

                                      if(!mot_trouver.equals(mot_chercher)) {

                                      OK. Ce qui me gêne un peu c'est que tu as deux fois la condition mot_trouver.equals(mot_chercher) dans la même méthode. Tu peux la tester une seule fois et faire un else. Mais il ne faut pas que ça change le résultat de la méthode! :ninja:

                                      Robin Mathieu a écrit:

                                      pour la modification avec le charAt je t'avoue que j'hesite beaucoup pour trois raisons:

                                      • Tout d'abord mes lettres sont stocker en tant que string donc faut modifier tout le programme plus une partie de la structure.(la flem :))

                                      En POO, on apprend à séparer les fonctionnalités de chaque classe pour éviter ce genre de problèmes. Tu ne dois pas être obligé de réécrire la moitié de ton programme simplement parce que tu as changé une virgule quelque part. Là on est déjà un niveau au-dessus du niveau débutant, mais c'est bon de le savoir.

                                      String est en soi un type inadapté pour tes lettres. Par nature tu veux un caractère, donc un char.
                                      Cela dit j'admets que ça va être pénible de gérer la concaténation String + char un peu partout si Java ne le fais pas implicitement (je ne sais pas, je n'ai pas essayé).
                                      Donc c'est une grosses remise en question, oui. Ca dépend de la qualité à laquelle tu veux tendre.

                                      Robin Mathieu a écrit:

                                      Ensuite si je stock en char je ne peut pas me servir du caractere vide pour la racine car un char ne tolère pas le caractère vide ni le null. Donc je dois mettre '\u0000' mais au final ça me rajoute un espace donc c'est vraiment pas terrible pour le traitement de phrase.(l'espace c'est important dans une phrase ^^)

                                      Tu peux utiliser le type Char (avec une majuscule). C'est une traduction de char en type objet et il peut être null. Pour les opérations simples il se comporte exactement comme un char.

                                      Robin Mathieu a écrit:

                                      Et enfin je vais beaucoup travailler sur les phrases bientôt donc je me demande si c'est pas mieux de tout mettre en string histoire d'avoir plus de facilité dans le traitement en évitant les conversions.

                                      Alors là oui, si tes branches deviennent des mots ou des phrases c'est un vrai argument pour garder des String.

                                      Robin Mathieu a écrit:

                                      Quand je dis que je vais beaucoup travailler sur les phrases c'est parce que je vais avoir un professeur particulier sur les réseaux de neurone pour y appliquer le dico que je suis entrain de faire.

                                      :waw: J'espère que tu es conscient :

                                      • de la différence entre ton niveau Java et le niveau d'informatique/algorithmique requis pour travailler sur des réseaux de neurones
                                      • du manque de fiabilité de ton programme en l'état. Tu es en apprentissage ! Pour jouer avec des réseaux de neurones il faut du matériel spécialisé, des algorithmes performants et des implémentations rapides (idéalement s'exécutant en C).

                                      Robin Mathieu a écrit:

                                      je te met aussi mon fichier test il est surement mal coder mais ca c'est pas grave il est vouer a disparaitre:

                                      Un fichier de test n'est jamais voué à disparaître. Tu le gardes précieusement pour vérifier que tu n'auras pas altéré le fonctionnement la prochaine fois que tu touches à ton programme.

                                      Robin Mathieu a écrit:

                                      Voili voilou merci encore pour tes conseils.

                                      De rien ! D'autres t'auraient sûrement dit des choses plus pertinentes. C'est un plaisir pour moi. :magicien:

                                      Prochain objectif que je te propose :

                                      Je te rappelle que tu m'as dit que c'était un challenge technique sur la récursivité et les arbres n-aires. Je crois que tu y es.
                                      Si tu veux vraiment faire ça de façon opérationnelle je t'encourage vivement à le réécrire avec des TreeMap et des boucles while/for.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        7 septembre 2019 à 9:59:06

                                        Bonjour, 

                                        pour la methode rechercher voila ce que j'ai fait du coup :

                                        public Mot_Data rechercher(Branche e, String mot_trouver, String mot_chercher) {
                                        	mot_trouver += e.getLettre();
                                        	if((mot_trouver.equals(mot_chercher))&&(e.getData() != null)) {
                                        		return e.getData();
                                        	}else{
                                        		for(Branche branche : e.getBranches()){
                                        			if(mot_chercher.substring(mot_trouver.length(), mot_trouver.length()+1).equals(branche.getLettre())){
                                        				return rechercher(branche,mot_trouver,mot_chercher);
                                        			}
                                        		}
                                        	}
                                        	return null;
                                        }

                                        ca marche tout aussi bien ^^

                                        Maintenant j'ai plusieurs question vis a vis de ce que tu as écrit :

                                        • pour les lettre en char, ce qui est important c'est que la classe contiennent une lettre de type char ou que toutes les manipulation se fassent sur des char ? puis je faire simplement une conversion dans le constructeurs de branche et la même conversion dans le get :
                                        public Branche (String let) {
                                        		this.Lettre = let.charAt(0);
                                        		this.branches = new ArrayList<Branche>();
                                        		this.data = null;
                                        	}

                                        et :

                                        public String getLettre() {
                                        		return Character.toString(this.Lettre);
                                        	}
                                        • Ensuite quand tu parle de séparé les fonctionnalité des classes qu'entend tu pars la ? et surtout en quoi n'est ce pas le cas ici ?
                                        • J'ai essayer d'implémenté le type Char avec la majuscule seulement il ne le reconnait pas comme classe déjà existante faut il la créer ?

                                        Pour les réseaux de neurones : 

                                        oui j'ai bien conscience de cet écart très grand, justement j'ai rendez vous avec mon prof pour en discuter et pour justement savoir d'ou on vas commencer sachant que le but est d'arriver au réseaux de neurone.

                                        Quand au matériel spécialisé et les algorithmes, je ne sais pas en quel point un réseaux de neurone est différent d'un perceptrons mais j'ai déjà coder un perceptrons sur reconnaissance de chiffre de 1 a 10 en java et les algorithmes était tout a fait a ma porter (j'avais 92% comme taux de bonne réponse ^^), enfin tout ça pour dire que je sais que je vais en baver mais je m'y suis préparer

                                        • Enfin sur les prochains objectifs:
                                        •  les TreeMap, j'ai regarder cela avec beaucoup d'attention néanmoins sauf si j'ai mal compris. le TreeMap est un arbre n-aire ordonnée et surtout proportionner or même si le coté gestion via le Treemap a l'aire très interressant, mon dictionnaire est très loin d'être proportionner.

                                        du coup je me demandais lorsque tu parle de prochain objectif, s'agirait il de travailler les Treemap avec autre chose que le dico, ou ai je mal compris le principe des Treemap

                                        • Les boucles while/for :
                                        déjà pour moi avant nos discutions un for je l'utilisé lorsque je voulais parcourir un tableau ou une liste du début a la fin et un while lorsque je ne voulais justement pas le lire jusque la fin, maintenant je m’aperçois que c'était idiot car les deux peuvent le faire mais dans ce cas quel est la vrai différence entre un while et un for ?

                                        -
                                        Edité par Robin Mathieu 7 septembre 2019 à 10:01:18

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          7 septembre 2019 à 15:43:21

                                          Pour char ou String :

                                          Char fait partie de la librairie standard. Il faut seulement l'importer en début de fichier, comme n'importe quelle autre classe.

                                          Les String sont des objets lourds. Ils sont immuables, donc chaque fois que tu fais une opération sur un String, Java crée de nouveaux objets String. Quand tu fais des concaténations à répétition c'est une plaie :

                                          "Hello" + " " + "World" + "!"
                                          // Ce code a instancié 7 objets String :
                                          // "Hello", " ", "World", "!",
                                          // "Hello ",
                                          // "Hello World"
                                          // "Hello World !"

                                          Stocker un caractère tout seul dans un String, ou utiliser substring pour extraire un caractère unique, c'est inutilement lourd pour la JVM.

                                          Au-delà de ça, Java possède les types char et Char pour représenter les caractères. Pourquoi utiliser des String, alors qu'ils sont fait pour des chaînes de caractères ?

                                          Ca fait partie des questions qu'on peut te poser en entretien d'embauche. Le choix du bon type participe à la qualité du code.

                                          Les TreeMap

                                          La question est la même que pour les Char, et la même que pour Lecture_Fichier : pourquoi réécrire à la main quelque chose qui est déjà implémenté par défaut et qui a été écrit par des spécialistes ?

                                          Réponse : parce que tu peux avoir besoin d'une implémentation précise pour un usage spécifique. Il y a par exemple de nombreuses implémentations de List, adaptées à différents usages.

                                          Je ne vois pas bien ce que tu appelles un arbre n-aire proportionné. Si tu as besoin d'une fonctionnalité ou d'une optimisation particulière que TreeMap ne peut pas te fournir, alors ça tient debout. Mais là, honnêtement, je ne vois pas ce que tu as de plus que TreeMap avec ton Dico.

                                          J'ai dit TreeMap parce qu'elle te permet de parcourir l'arbre par ordre alphabétique, mais si l'ordre des mots n'a pas d'importance tu peux aussi utiliser n'importe quelle Map.

                                          While/For

                                          For est utile quand tu fais une itération, en particulier quand tu as besoin d'un compteur qui te dit combien de fois la boucle a déjà été exécutée.

                                          While s'utilise plutôt quand on ne sait pas à l'avance combien de fois on va utiliser la boucle.

                                          Do...while s'utilise dans les mêmes cas que While mais quand on veut que la boucle s'exécute au moins une fois.

                                          For et while sont interchangeables, c'est-à-dire que tu arriveras toujours à utiliser l'un à la place de l'autre. Mais il y en a souvent un des deux qui est plus naturel.
                                          Dans ton cas, implémenter un while et incrémenter un compteur dans la boucle, c'est un artifice qui prouve qu'un for était plus adapté.

                                          Prochain objectif :

                                          Je te trouve encore très fragile que les questions d'algorithmique, ce qui n'est pas propre à Java.

                                          Tes boucles while/for ne sont pas claires, d'ailleurs tu te poses des questions (et c'est bien !). Tes conditions if ne sont pas optimisées et souvent redondantes.

                                          Quand tu as eu un problème de dépassement du substring, c'est parce que tu n'avais pas pensé à gérer le cas où le mot n'existe pas, mais où sa branche existe (parce que c'est le début d'un mot connu). Personnellement j'aurais testé mot_chercher.equals(mot_trouver) et e.getData()==null dans des conditions différentes, avec des conséquences distinctes. Au moins on sait ce qui se passe dans le cas du mot qui n'a pas de Data !
                                          Tu peux comparer avec le code que je t'avais suggéré ici.

                                          Donc comme je te l'ai dit, c'était un bon défi sur la récursivité. C'est très bien quand on débute sur un langage, c'est comme ça qu'on apprend.
                                          Mais je te parie que dans moins de 6 mois tu seras incapable de modifier ton code sans casser tout le programme, parce que les boucles sont .
                                          Si tu réécris le même programme avec des TreeMap et une forme itérative, tu auras moins de classes, moins de lignes de code, un programme plus clair et probablement plus performant.

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            8 septembre 2019 à 9:16:40

                                            Coucou

                                            bon suite a ton message, je me suis décider a le refaire avec Treemap, seulement beaucoup de mal a trouver par ou commencer peut tu me conseiller un cours ? ou un site qui en parle et me permetterai de bien commencer ?

                                            -
                                            Edité par Robin Mathieu 8 septembre 2019 à 9:17:14

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              9 septembre 2019 à 10:18:06

                                              En récursif, il "suffit" de remplacer ton ArrayList<Branche> par une TreeMap.
                                              L'intérêt serait de le faire en itératif. Donc avec une seule boucle qui parcourt les lettres du mot à ajouter/rechercher, et qui crée/sélectionne la bonne TreeMap.

                                              Tu n'as plus besoin de rechercher la "bonne" sous-branche, puisque la méthode TreeMap.get() te permet d'y accéder directement.

                                              Pour que ce soit bien clair : une TreeMap ne représente pas l'arbre entier, mais seulement un noeud qui te permet d'accéder aux sous-branches.
                                              Tu utiliseras donc le type TreeMap<String, Branche> ou TreeMap<Char, Branche>.

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                9 septembre 2019 à 19:45:29

                                                Aaaa oki mais je pourrai quand même mettre mon mot_data ?
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  10 septembre 2019 à 9:29:06

                                                  Oui c'est un attribut de la classe Branche.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    10 septembre 2019 à 10:16:45

                                                    Cool je vais faire ça alors, j'essaye juste de finir les deux fonctions(chargement de la sauvegarde puis ajout de nouveau mot) qui me manque avant de mettre en place les Treemaps, et d’ailleurs je me heurte a une erreur que je comprend pas lors de la fonction de chargement du fichier de sauvegarde

                                                    Voila les méthodes de chargement du fichier de sauvegarde :

                                                    /*** Methodes de chargement ***/
                                                    		
                                                    		public void chargement(Branche e) {
                                                    			System.out.println("Début de chargement ...");
                                                    			try (InputStream ips=new FileInputStream("Data/Sauvegarde"); 
                                                    					InputStreamReader ipsr=new InputStreamReader(ips, "UTF8");
                                                    					BufferedReader reader=new BufferedReader(ipsr);)  {
                                                    				traitement(e,reader);
                                                    			} catch (IOException i) {
                                                    				System.out.println(i);
                                                    			}
                                                    			System.out.println("Chargement terminée .");
                                                    		}
                                                    		
                                                    		public void traitement(Branche e, BufferedReader reader) {
                                                    			try {
                                                    				int n = 0;
                                                    				while((n = reader.read()) != -1) {
                                                    					Character c = (char) n;
                                                    					System.out.print(c);
                                                    					switch(c) {
                                                    					case '(':
                                                    						e.getBranches().add(new Branche());
                                                    						traitement(e.getBranches().get(e.getBranches().size()-1), reader);
                                                    						break;
                                                    					case '|':
                                                    						traitement_data(e,reader);
                                                    						break;
                                                    					case ')':
                                                    						break;
                                                    					default:
                                                    						e.setLettre(c);
                                                    						break;
                                                    					}
                                                    				}
                                                    			} catch (IOException e1) {
                                                    				// TODO Auto-generated catch block
                                                    				e1.printStackTrace();
                                                    			}
                                                    		}
                                                    		
                                                    		public void traitement_data(Branche e, BufferedReader reader) {
                                                    			try {
                                                    				int n = 0;
                                                    				while((n = reader.read()) != 124) {
                                                    					Character c = (char) n;
                                                    					System.out.print(c);
                                                    					int cptp = 0;
                                                    					String tmp = "";
                                                    					if(c == '.') {
                                                    						cptp++;
                                                    						if(!tmp.isEmpty()) {
                                                    							switch(cptp) {
                                                    							case 0:
                                                    								e.getData().setLemme(tmp);
                                                    								break;
                                                    							case 1:
                                                    								e.getData().setCgram(tmp);
                                                    								break;
                                                    							case 2:
                                                    								e.getData().setGenre(tmp);
                                                    								break;
                                                    							case 3:
                                                    								e.getData().setNombre(tmp);
                                                    								break;
                                                    							case 4:
                                                    								if(tmp.equals("true")) {
                                                    									e.getData().setIslem(true);
                                                    								}else if(tmp.equals("false")){
                                                    									e.getData().setIslem(false);
                                                    								}
                                                    								break;
                                                    							default:
                                                    								break;
                                                    							}
                                                    						}
                                                    						tmp = "";
                                                    					}else {
                                                    						tmp += e.getLettre();
                                                    					}
                                                    				}
                                                    			} catch (IOException e1) {
                                                    				// TODO Auto-generated catch block
                                                    				e1.printStackTrace();
                                                    			}
                                                    		}

                                                    je te met le début du fichier de sauvegarde histoire que tu vois la tête :

                                                    (a(|avoir.VER...false| (c(a(p(e(l(l(a(|a capella.ADV...true|))))p(e(l(l(a(|a cappella.ADV...true|)))))))o(n(t(r(a(r(i(o(|a contrario.ADV...true|)))))))))f(o(r(t(i(o(r(i(|a fortiori.ADV...true|))))))))

                                                    la ( signale une descente dans l'arbre tandis que ) signale une remonter le | lui signale le début d'un mot data.

                                                    et voila l'erreur du compilateur:

                                                    at java.util.HashMap.getNode(Unknown Source)
                                                    	at java.util.HashMap.get(Unknown Source)
                                                    	at java.nio.charset.CoderResult$Cache.get(Unknown Source)
                                                    	at java.nio.charset.CoderResult$Cache.access$200(Unknown Source)
                                                    	at java.nio.charset.CoderResult.unmappableForLength(Unknown Source)
                                                    	at sun.nio.cs.SingleByte$Encoder.encodeArrayLoop(Unknown Source)
                                                    	at sun.nio.cs.SingleByte$Encoder.encodeLoop(Unknown Source)
                                                    	at java.nio.charset.CharsetEncoder.encode(Unknown Source)
                                                    	at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
                                                    	at sun.nio.cs.StreamEncoder.write(Unknown Source)
                                                    	at java.io.OutputStreamWriter.write(Unknown Source)
                                                    	at java.io.BufferedWriter.flushBuffer(Unknown Source)
                                                    	at java.io.PrintStream.write(Unknown Source)
                                                    	at java.io.PrintStream.print(Unknown Source)
                                                    	at Dico.traitement_data(Dico.java:204)
                                                    	at Dico.traitement(Dico.java:184)
                                                    	at Dico.traitement(Dico.java:181)
                                                    	at Dico.traitement(Dico.java:181)
                                                    	at Dico.traitement(Dico.java:181)

                                                    Si tu as une idée ca me dépannerai bien.


                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      10 septembre 2019 à 14:37:17

                                                      Ca vient de cette ligne :
                                                      while((n = reader.read()) != 124) {

                                                      Pourquoi 124 ?? o_O
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        11 septembre 2019 à 7:59:02

                                                        dsl j'ai pas expliquer 124 c'est le cast de '|' en int et il en passe plusieurs tu as du voir que j'ai mis des print pour voir a quel moment ca plante il me lie la sauvegarde sur une soixantaine de mots environ ensuite il commence a me mettre des point d'interrogation a la place des accents alors qu'il en as lu avant puis fini par planter

                                                        -
                                                        Edité par Robin Mathieu 11 septembre 2019 à 7:59:52

                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          11 septembre 2019 à 14:16:09

                                                          Et comment tu as prévu la fin du traitement de traitement_data ? Quand est-ce que ça s'arrête ?:-°

                                                          Accessoirement j'aimerais bien avoir le texte compler de l'exception parce que tu n'as pas donné le début.

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            11 septembre 2019 à 15:34:02

                                                            Oui tu as raison voici le resultat du compilateur, par contre il n'y a pas tout encore une fois ca fait completement planter trop de texte donc je t'ai juste mis la fin de l'affichage :

                                                            .VER...false)z(|activer.VER...false))i(s(m(e(|activisme.NOM.m.s.true))t(e(|activiste.NOM..s.trues(|activiste.NOM..p.false))))t(?(|activit?.NOM.f.s.trues(|activit?.NOM.f.p.false))))o(n(s(|activer.VER...false)))?(r(e(n(t(|activer.VER...false)))))?(|activ?.ADJ.m.s.truee(|activ?.ADJ.f.s.falses(|activ?.ADJ.f.p.false))s(|activ?.ADJ.m.p.false))))r(i(c(e(|acteur.NOM.f.s.falses(|acteur.NOM.f.p.false)))))u(a(i(r(Exception in thread "main" java.lang.StackOverflowError
                                                            	at java.nio.charset.CharsetEncoder.encode(Unknown Source)
                                                            	at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
                                                            	at sun.nio.cs.StreamEncoder.write(Unknown Source)
                                                            	at java.io.OutputStreamWriter.write(Unknown Source)
                                                            	at java.io.BufferedWriter.flushBuffer(Unknown Source)
                                                            	at java.io.PrintStream.write(Unknown Source)
                                                            	at java.io.PrintStream.print(Unknown Source)
                                                            	at Dico.traitement(Dico.java:177)
                                                            	at Dico.traitement(Dico.java:181)
                                                            	at Dico.traitement(Dico.java:181)
                                                            	at Dico.traitement(Dico.java:181)

                                                            en dessous je te remet le passage concerner dans la sauvegarde :

                                                            .VER...false|)z(|activer.VER...false|))i(s(m(e(|activisme.NOM.m.s.true|))t(e(|activiste.NOM..s.true|s(|activiste.NOM..p.false|))))t(é(|activité.NOM.f.s.true|s(|activité.NOM.f.p.false|))))o(n(s(|activer.VER...false|)))è(r(e(n(t(|activer.VER...false|)))))é(|activé.ADJ.m.s.true|e(|activé.ADJ.f.s.false|s(|activé.ADJ.f.p.false|))s(|activé.ADJ.m.p.false|))))r(i(c(e(|acteur.NOM.f.s.false|s(|acteur.NOM.f.p.false|)))))u(a(i(r

                                                            d'après ce que j'ai compris il y a un problème lorsqu'il rencontre le second '|' qui est censé marquer la fin de la collecte de mot_data et toujours le problème avec UTF8 ou il lit pas les accents.

                                                            seulement je vois vraiment pas le problème dans le code.

                                                            PS:pour repondre a ta question la condition du while de chaque fonction met fin au traitement normalement:

                                                            while((n = reader.read()) != 124)

                                                            ca c'est pour la fin de la fonction traitement_data

                                                            while((n = reader.read()) != -1)

                                                            ici pour la fin de la fonction traitement

                                                            Edit: j'ai rien dit sur la supposé erreur le second '|' ne s'affiche pas mais c'est normal (dans le test de chargement), il y a le problème des accent et le :

                                                            Exception in thread "main" java.lang.StackOverflowError




                                                            -
                                                            Edité par Robin Mathieu 11 septembre 2019 à 15:38:21

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              11 septembre 2019 à 16:25:29

                                                              Ok compris pour le 124. J'avais lu trop vite.

                                                              Exception in thread "main" java.lang.StackOverflowError

                                                              Le problème est là : tu as un dépassement de la pile d'exécution. C'est quand il y trop d'appels imbriqués de fonctions.

                                                              C'est typiquement le problème d'un algorithme récursif sur des données volumineuses. Je suis un peu surpris parce que je n'ai pas l'impression que tu aies plus d'appels imbriqués que ceux qui sont nécessaires à traiter la longueur d'un mot dans traitement().

                                                              Quoi qu'il en soit j'y (re)vois l'intérêt de réécrire ton programme en itératif.

                                                              Quant aux accents c'est normal. La console ne les affiche pas mais ça ne veut pas dire qu'ils n'ont pas été traités correctement.

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Affichage Arbre n aire

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown