Condition qui n'est jamais vérifiée

Résolu/Fermé
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 - 9 mars 2021 à 18:36
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 - 17 mars 2021 à 15:06
Bonjour, avec une fonction j'essaie de passer dans un if, mais la condition n'est jamais vérifiée, et je ne vois pas pourquoi. J'ai bien débuggué pendant 2 heures au moins, mais rien trouvé. La seule chose de bizarre que j'ai pu voir (mais normale, j'imagine?) est que la taille de mon objet est de 0, alors qu'elle contient un hashmap.

public static void main(String[] args){

        // création du dictionnaire
        Dico dico = new Dico("C:\\Users\\Slash\\IdeaProjects\\2-somme\\src\\com\\company\\Dico.txt");

        // création de la table de hashage qui contient tous les mots du dico, réunis par clef
        HashTable tableHashage = new HashTable();
        tableHashage = tableHashage.addDicoToHashMap(dico);

        // choix d'un mot random parmi tous ceux générés à partir de l'ensemble
        Mot ensemble = new Mot("bonjour");

        //deux sommes
        Mot.deuxSomme(dico, tableHashage, ensemble);

    }


public static boolean deuxSomme(Dico dico, HashTable hashtable, Mot ensemble){

        // mots M2 du dico
        // contenus dans l'ensemble R, le mot M1 sur lequel est appelé la méthode
        List motsEnsembleR = dico.getAllMotsAvec(ensemble.getMot());


        // obtient le complément de chaque mot contenu dans R et cherche s'il existe dans le hashmap tel que
        // ensembleR (M1) = mot dico (M2) + mot2 hashmap (M3)
        for (int i = 0; i < motsEnsembleR.size() ; i++) {

            // création de chaque complément de chaque sous mot de l'ensemble R
            Mot mot = new Mot(motsEnsembleR.get(i).toString());
            Mot complement = new Mot(ensemble.remove((Mot) motsEnsembleR.get(i)).toString());
            System.out.println(complement.toString());

            if (hashtable.hashmap.containsValue(complement)){
                System.out.println(ensemble+"(M1) = "+motsEnsembleR.get(i).toString()+" (M2) + "+complement.toString()+" (M3)");
                return true;
            }

        }

        // si aucun complément n'a été trouvé
        System.out.println("aucun complément n'a été trouvé");
        return false;
    }


public boolean containsValue(Mot mot){
        Key key = new Key(mot);

        if (this.hashmap.get(key.toString()) == null){

            return false;
        }
        else{
            for (int i = 0; i < this.hashmap.get(key.toString()).size(); i++) {

                if (this.hashmap.get(key.toString()).get(i).toString().equals(mot.toString())){
                    return true;
                }
            }

            return false;
        }
    }

4 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
9 mars 2021 à 19:10
Bonjour,

Il faudrait que tu fournisses un code complet pour trouver le problème, parce que les petits morceaux de code que tu as mis sont insuffisants pour pouvoir tester le programme en détail.

Ce serait aussi l'occasion de te donner quelques conseils sur l'ensemble du code, parce qu'au fur et à mesure de tes différentes discussions il s'est complexifié, ce qui peut aussi expliquer les problèmes qui s'accumulent.
0
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 1
Modifié le 12 mars 2021 à 22:45
Salut, merci pour ta réponse.

Ce qui me pose problème, c'est le résultat de la méthode deuxSomme(): à partir d'un mot, elle vérifie s'il existe des sous-chaines telles que l'une vient du dictionnaire et l'autre de la HashMap.

Par exemple: pour le mot "bonjour", on devrait obtenir (entre autre, mais pas seulement):
bonjour = bon (provenant du dico) + jour (provenant de la hashmap)

Sauf qu'elle m'indique à chaque fois qu'elle ne trouve rien.


Main
package com.company;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class Main {

    public static void main(String[] args){

        // création du dictionnaire
        Dico dico = new Dico("C:\\Users\\Slash\\IdeaProjects\\2-somme\\src\\com\\company\\Dico.txt");

        // création de la table de hashage qui contient tous les mots du dico, réunis par clef

        HashTable tableHashage = new HashTable();
        tableHashage = tableHashage.addDicoToHashMap(dico);

        // création d'un mot
        Mot ensemble = new Mot("bonjour");

        //deux sommes
        Mot.deuxSomme(dico, tableHashage, ensemble);


    }
}


Mot
package com.company;
import java.util.*;

public class Mot {

    private final String mot;
    private String lettresTriees;



    public Mot(String mot) {
        this.mot = mot;
    }

    public String getMot(){
        return mot;
    }

    public int length(){
        return mot.length();
    }

    public String toString(){
        return mot;
    }


    public String getLettresTriees(){
        if (lettresTriees == null) {
            char[] lettres = mot.toCharArray();
            Arrays.sort(lettres);
            lettresTriees = new String(lettres);
        }
        return lettresTriees;
    }


    public boolean contains(Mot mot) {
        // le mot doit être plus petit que l'ensemble pour pouvoir être contenu
        if (this.length() <= mot.length())
            return false;

        String lettresEnsemble = this.getLettresTriees();
        String lettresMot = mot.getLettresTriees();
        int iE = 0, iM = 0;

        while (iE < this.length() && iM < mot.length()) {
            if (lettresEnsemble.charAt(iE) == lettresMot.charAt(iM)) {
                iE++;
                iM++;
            } else if (lettresEnsemble.charAt(iE) < lettresMot.charAt(iM)) {
                iE++;
            } else {
                return false;
            }
        }
        return iM == mot.length();
    }


    // permet d'obtenir le complément d'un mot par rapport à son ensemble
    public String remove(Mot mot) {
        String lettres = getLettresTriees();
        String lettres2 = mot.getLettresTriees();
        char[] result = new char[length()];
        int i = 0, i2 = 0, n = 0;
        while (i < length() && i2 < mot.length()) {
            if (lettres.charAt(i) == lettres2.charAt(i2)) {
                i++;
                i2++;
            } else if (lettres.charAt(i) < lettres2.charAt(i2)) {
                result[n] = lettres.charAt(i);
                n++;
                i++;
            } else {
                i2++;
            }
        }
        while (i < length()) {
            result[n] = lettres.charAt(i);
            n++;
            i++;
        }
        return new String(Arrays.copyOf(result, n));
    }


    public String remove2 (Mot ensemble){
        String complement = ensemble.getMot().toString();
        for(char c:mot.toCharArray()){
            // supprime la lettre (dans ensemble) équivalente à la lettre c (dans mot)
            complement=complement.replaceFirst(""+c, "");
        }
        return complement;
    }




    public static boolean deuxSomme(Dico dico, HashTable hashtable, Mot ensemble){

        // mots M2 du dico
        // contenus dans l'ensemble R, le mot M1 sur lequel est appelé la méthode
        List motsEnsembleR = dico.getAllMotsAvec(ensemble.getMot());


        // obtient le complément de chaque mot contenu dans R et cherche s'il existe dans le hashmap tel que
        // ensembleR (M1) = mot dico (M2) + mot2 hashmap (M3)
        for (int i = 0; i < motsEnsembleR.size() ; i++) {

            // création de chaque complément de chaque sous mot de l'ensemble R
            Mot mot = new Mot(motsEnsembleR.get(i).toString());
            Mot complement = new Mot(ensemble.remove((Mot) motsEnsembleR.get(i)).toString());
            System.out.println(complement.toString());

            if (hashtable.hashmap.containsValue(complement)){
                System.out.println(ensemble+"(M1) = "+motsEnsembleR.get(i).toString()+" (M2) + "+complement.toString()+" (M3)");
                return true;
            }

        }

        // si aucun complément n'a été trouvé
        System.out.println("aucun complément n'a été trouvé");
        return false;
    }



    /**
     * test
     */
    public static void main(String[] args){

        Mot ensemble = new Mot("bonjour");
        Mot mot = new Mot("jour");

        System.out.println(ensemble.contains(ensemble)); // false car de taille égale
        System.out.println(ensemble.contains(mot)); // true

        // complément du mot
        System.out.println(ensemble.remove(mot));


        Mot ensemble2 = new Mot("papillon");
        Mot mot2 = new Mot("papi");
        System.out.println(ensemble2.toString());
        System.out.println(mot2.toString());
        System.out.println(ensemble2.remove2(mot2));


    }

}


Dico
package com.company;
import java.util.*;

public class Mot {

    private final String mot;
    private String lettresTriees;



    public Mot(String mot) {
        this.mot = mot;
    }

    public String getMot(){
        return mot;
    }

    public int length(){
        return mot.length();
    }

    public String toString(){
        return mot;
    }


    public String getLettresTriees(){
        if (lettresTriees == null) {
            char[] lettres = mot.toCharArray();
            Arrays.sort(lettres);
            lettresTriees = new String(lettres);
        }
        return lettresTriees;
    }


    public boolean contains(Mot mot) {
        // le mot doit être plus petit que l'ensemble pour pouvoir être contenu
        if (this.length() <= mot.length())
            return false;

        String lettresEnsemble = this.getLettresTriees();
        String lettresMot = mot.getLettresTriees();
        int iE = 0, iM = 0;

        while (iE < this.length() && iM < mot.length()) {
            if (lettresEnsemble.charAt(iE) == lettresMot.charAt(iM)) {
                iE++;
                iM++;
            } else if (lettresEnsemble.charAt(iE) < lettresMot.charAt(iM)) {
                iE++;
            } else {
                return false;
            }
        }
        return iM == mot.length();
    }


    // permet d'obtenir le complément d'un mot par rapport à son ensemble
    public String remove(Mot mot) {
        String lettres = getLettresTriees();
        String lettres2 = mot.getLettresTriees();
        char[] result = new char[length()];
        int i = 0, i2 = 0, n = 0;
        while (i < length() && i2 < mot.length()) {
            if (lettres.charAt(i) == lettres2.charAt(i2)) {
                i++;
                i2++;
            } else if (lettres.charAt(i) < lettres2.charAt(i2)) {
                result[n] = lettres.charAt(i);
                n++;
                i++;
            } else {
                i2++;
            }
        }
        while (i < length()) {
            result[n] = lettres.charAt(i);
            n++;
            i++;
        }
        return new String(Arrays.copyOf(result, n));
    }


    public String remove2 (Mot ensemble){
        String complement = ensemble.getMot().toString();
        for(char c:mot.toCharArray()){
            // supprime la lettre (dans ensemble) équivalente à la lettre c (dans mot)
            complement=complement.replaceFirst(""+c, "");
        }
        return complement;
    }




    public static boolean deuxSomme(Dico dico, HashTable hashtable, Mot ensemble){

        // mots M2 du dico
        // contenus dans l'ensemble R, le mot M1 sur lequel est appelé la méthode
        List motsEnsembleR = dico.getAllMotsAvec(ensemble.getMot());


        // obtient le complément de chaque mot contenu dans R et cherche s'il existe dans le hashmap tel que
        // ensembleR (M1) = mot dico (M2) + mot2 hashmap (M3)
        for (int i = 0; i < motsEnsembleR.size() ; i++) {

            // création de chaque complément de chaque sous mot de l'ensemble R
            Mot mot = new Mot(motsEnsembleR.get(i).toString());
            Mot complement = new Mot(ensemble.remove((Mot) motsEnsembleR.get(i)).toString());
            System.out.println(complement.toString());

            if (hashtable.hashmap.containsValue(complement)){
                System.out.println(ensemble+"(M1) = "+motsEnsembleR.get(i).toString()+" (M2) + "+complement.toString()+" (M3)");
                return true;
            }

        }

        // si aucun complément n'a été trouvé
        System.out.println("aucun complément n'a été trouvé");
        return false;
    }



    /**
     * test
     */
    public static void main(String[] args){

        Mot ensemble = new Mot("bonjour");
        Mot mot = new Mot("jour");

        System.out.println(ensemble.contains(ensemble)); // false car de taille égale
        System.out.println(ensemble.contains(mot)); // true

        // complément du mot
        System.out.println(ensemble.remove(mot));


        Mot ensemble2 = new Mot("papillon");
        Mot mot2 = new Mot("papi");
        System.out.println(ensemble2.toString());
        System.out.println(mot2.toString());
        System.out.println(ensemble2.remove2(mot2));


    }

}


HashTable
package com.company;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class HashTable extends HashMap {


    /**
     * table de hashage
     */
    public HashMap<String, ArrayList<Mot>> hashmap;



    // création d'une table de hachage
    public HashTable(){
        this.hashmap = new HashMap();
    }



    public void put(String key, Mot mot) {

        if (hashmap.get(key) == null) {
            ArrayList<Mot> anagramme = new ArrayList<>();
            hashmap.put(key, anagramme);
            anagramme.add(mot);
        }
        else{
            hashmap.get(key).add(mot);
        }

    }


    // vérifie si la table de hachage contient une ArrayList qui contient elle-même un certain mot

    public boolean containsValue(Mot mot){
        Key key = new Key(mot);

        if (this.hashmap.get(key.toString()) == null){

            return false;
        }
        else{
            for (int i = 0; i < this.hashmap.get(key.toString()).size(); i++) {

                if (this.hashmap.get(key.toString()).get(i).toString().equals(mot.toString())){
                    return true;
                }
            }

            return false;
        }
    }


    // vérifie si la table de hachage contient une certaine clef
    public boolean containsKey(Key key){
        return this.hashmap.get(key)!=null;
    }



    // retourne le ou les élément(s) à partir d'une clef
    public ArrayList<Mot> get(Key key){
        return this.hashmap.get(key);
    }



    // affiche le contenu d'un hashMap
    public void printContent(){
        System.out.println("\n\t↓ HASHMAP CONTENT ↓");
        System.out.println("\t [KEY]: [VALUE]");
        for (Map.Entry m: this.hashmap.entrySet()) {
            System.out.println("  " + m.getKey().toString() + " : " + m.getValue());
        }
        System.out.println("");
    }




    //ajoute tous les mots du dictionnaire au hashamp
    public HashTable addDicoToHashMap(Dico dico){

        HashTable hm = new HashTable();

        // pour chaque mot du dictionnaire
        for(int i=0;i<dico.getAllMots().size();i++){

            // création du mot, de sa clef, et ajout au hashmap
            Mot mot = new Mot(dico.getAllMots().get(i).toString());
            Key key = new Key(mot);

           hm.put(key.toString(), mot);
        }

        return hm;
    }



    /**
     * test
     */
    public static void main(String[] args) throws FileNotFoundException {

        //création du dico
        Dico dico = new Dico("C:\\Users\\Slash\\IdeaProjects\\2-somme\\src\\com\\company\\Dico.txt");

        // création de la table de hashage
//        HashTable hm = new HashTable();
//
//
//        // ajout d'une clef et d'un mot (en passant par une ArrayList)
//        Mot mot1 = new Mot("bonjour");
//        Key clef = new Key(mot1); // 67
//        hm.put(clef.toString(), mot1);
//        System.out.println(clef.toString());
//        hm.printContent();
//
//
//        // 2ème essai: mot différent avec clef différente de même valeur
//        Mot mot2 = new Mot("jourbon");
//        Key clef2 = new Key(mot2); // 67
//        System.out.println(clef2.toString());
//        hm.put(clef2.toString(), mot2);
//        hm.printContent();
//
//
//        System.out.println(hm.containsValue(mot1)); // true
//        System.out.println(hm.containsValue(mot2)); // true
//
//        Mot mot3 = new Mot("koala");
//        Key key3 = new Key(mot3);
////        hm.put(key3.toString(), mot3);
//        System.out.println(hm.containsValue(mot3)); // false car non ajouté


        ///////////////////////////////
        // ajoute tous les mots du dico au hashmap
        HashTable hm2 = new HashTable();
        hm2 = hm2.addDicoToHashMap(dico);
        hm2.printContent();

        Mot mot5 = new Mot("écurerez");
        System.out.println(hm2.containsValue(mot5));


    }
}


Key
package com.company;

import java.io.FileNotFoundException;
import java.util.HashMap;

public class Key {

    String key;

    //génération de la clé d'un mot
    public Key(Mot mot){
        this.key = generateKey(mot);
    }

    public String generateKey(Mot mot){
        return mot.getLettresTriees();
    }

    public String toString(){
        return key;
    }

    public boolean isEqualTo(Key key2){
        return this.toString() == key2.toString();
    }

    /**
     * test
     */
    public static void main(String[] args) {

        Mot mot = new Mot("bonjour");
        Key key = new Key(mot);
        System.out.println("la clef du mot \""+ mot.getMot() + "\" est " + key.toString());

        Mot mot2 = new Mot("jobonru");
        Key key2 = new Key(mot2);
        System.out.println("la clef du mot2 \"" + mot2.getMot() + "\" est " + key2.toString());

        System.out.println(key.isEqualTo(key)); // true

        System.out.println(key == key2); // false car 2 objets différents

        System.out.println(key.toString().equals(key2.toString())); // true car de même valeur

    }

}


Complement
package com.company;

public class Complement {

    private final String complement;

    public Complement(Dico dico, Mot ensemble) {
        System.out.println("l'ensemble est : " + ensemble.getMot());

        // choix d'un mot random parmi tous ceux générés à partir de l'ensemble
        Mot mot = dico.getRandomMotAvec(ensemble.getMot());
        System.out.println("le mot choisi aléatoirement est : " + mot);

        // ensemble - mot random = complement
        this.complement = ensemble.remove(mot);
    }

    public String getComplement(){
        return complement;
    }


    /**
     * test
     */
    public static void main(String[] args){

        // création du dictionnaire
        Dico dico = new Dico("C:\\Users\\Slash\\IdeaProjects\\2-somme\\src\\com\\company\\Dico.txt");
        Mot ensemble = new Mot("bonjour");

        // obtention du complément d'un mot par rapport à son ensemble
        Complement complement = new Complement(dico, ensemble);
        System.out.println("le complément est : " + complement.getComplement());

    }


}
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
13 mars 2021 à 09:34
Bonjour,

Tu as mis deux fois le code de Mot et il manque le code de Dico.
0
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 1 > KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024
14 mars 2021 à 18:45
Pardon, autant pour moi.

Voilà le code de Dico:

package com.company;
import java.io.*;
import java.nio.file.*;
import java.util.*;

public class Dico {

    private static final Random random = new Random();
    private final List<Mot> mots;

    public Dico(String fileName) {
        mots = new ArrayList<>();
        try {
            for (String line : Files.readAllLines(Paths.get(fileName))) {
                mots.add(new Mot(line));
            }
        } catch (IOException e) {
            throw new UncheckedIOException("Impossible de lire " + fileName, e);
        }
    }

    // génère tous les mots possibles à partir d'un ensemble donné en paramètre
    public List<Mot> getAllMotsAvec(String lettres) {
        Mot ensemble = new Mot(lettres);

        List<Mot> result = new ArrayList<>();
        for (Mot mot : mots) {
            if (ensemble.contains(mot)) { // si mot du dictionnaire est inclus dans ensemble
                result.add(mot);
            }
        }
        return Collections.unmodifiableList(result);
    }

    public List<Mot> getAllMots(){
        return Collections.unmodifiableList(mots);
    }

    public Mot getRandomMotAvec(String lettres) {
        List<Mot> liste = getAllMotsAvec(lettres);
        if (liste.isEmpty())
            return null;
        return liste.get(random.nextInt(liste.size()));
    }

    /**
     * test
     */
    public static void main(String[] args) throws FileNotFoundException {

        Dico dico = new Dico("C:\\Users\\Slash\\IdeaProjects\\2-somme\\src\\com\\company\\Dico.txt");

        // tous les mots possibles à partir de l'ensemble
        Mot ensembleR = new Mot("bonjour");
        System.out.println(dico.getAllMotsAvec(ensembleR.getMot())); // bon, jour, bonjour, juron, ...

        // choix d'un random parmis ces mots
        Mot mot = dico.getRandomMotAvec("bonjour");
        System.out.println(mot); // brun, job, bon par ex


        // 1 on itère i sur tous les mots possibles contenus dans cet ensemble
        // 2 on itère j sur tous les mots possibles pour voir si les deux mots forment un 2-somme
//        List motsEnsembleR = dico.getAllMotsAvec(ensembleR.getMot());
//        for (int i = 0; i<motsEnsembleR.size(); i++){
//            for (int j = 0; j<motsEnsembleR.size(); j++){
//                if (i==j){
//                    continue; //pour éviter d'avoir 2 fois le même mot
//                }
//
//                // si il y a deux mots concaténés qui sont égaux à l'ensemble R
//                if(motsEnsembleR.get(i).toString()+motsEnsembleR.get(j).toString()==ensembleR.getMot()){
//
//                    System.out.println(motsEnsembleR.get(i).toString() + motsEnsembleR.get(j).toString());
//
//                }
//            }
//        }




    }


}

0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
15 mars 2021 à 09:46
Bonjour,

Dans Mot, je trouve bizarre dans contains d'avoir
if (this.length() <= mot.length()) { return false; }
, ce qui signifie par exemple que "bonjour" n'est pas contenu dans "bonjour" alors qu'il devrait (en tout cas c'est ce que font d'autres méthodes "contains" en Java).
En conséquence getAllMotsAvec("bonjour") ne renvoie pas "bonjour"

Ensuite, dans deuxSomme, dico.getAllMotsAvec renvoie une List<Mot>, il faut donc conserver ce type, si tu écris juste List, sans paramètre, c'est considéré comme une liste d'Object.
Du coup tu te retrouves obligé de manipuler des
Object element : motsEnsembleR
que tu dois convertir en String pour retrouver des Mot... alors que c'était déjà des Mot !
C'est d'ailleurs une remarque générale, tous les types List<E> (ArrayList<E> etc.), Map<K,V> (HashMap<K,V> etc.) ont des types paramétrés, ils devraient donc être systématiquement mis, sinon c'est Object par défaut.

En gros :
List motsEnsembleR = dico.getAllMotsAvec(ensemble.getMot());
for (Object element : motsEnsembleR) {
     Mot mot = new Mot(element.toString());
     Mot complement = new Mot(ensemble.remove((Mot) element).toString());

Se simplifie en :
List<Mot> motsEnsembleR = dico.getAllMotsAvec(ensemble.getMot());
for (Mot mot : motsEnsembleR) {
     Mot complement = new Mot(ensemble.remove(mot));

Remarque : sémantiquement, tu ne devrais pas créer un Mot à partir d'un ensemble quelconque de lettres, un Mot doit être associé à une entrée dans le dictionnaire.
Exemple : "bonjour" est un mot, "bon" est un mot, si tu supprimes "bon" de "bonjour" cela te donne un ensemble de lettres : "joru", mais ce n'est pas un Mot.

Quant à ton problème, il vient de
if (hashtable.hashmap.containsValue(complement)) {
qui sera toujours faux, car hashmap est une HashMap<String, ArrayList<Mot>> alors que complement est un Mot, donc effectivement tu ne rentres jamais dans le if, car il n'y a aucune ArrayList<Mot> qui sera égale à un Mot.

Il faudrait plutôt faire quelque chose comme ça :
ArrayList<Mot> motsComplements = hashtable.get(ensemble.remove(mot));
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
Modifié le 16 mars 2021 à 09:02
En regardant ton code un peu plus en détail, je pense :

1) la classe Key est intéressante (mais mal nommée), elle devrait être davantage utilisée, en particulier pour alléger la classe Mot.
2) les classes HashTable et Dico devraient être fusionnées, en remplaçant la liste de Dico par la map de HashTable.
3) ta classe Complement ne sert à rien, il faudrait plutôt se baser sur la méthode remove.

Voici un exemple de restructuration du code :
package com.company;

import java.util.*;

public class EnsembleLettres {

    private final String lettres;

    public EnsembleLettres(final String lettres) {
        final char[] chars = lettres.toCharArray();
        Arrays.sort(chars);
        this.lettres = new String(chars);
    }

    public String getLettres(){
        return lettres;
    }

    public int length(){
        return lettres.length();
    }

    public EnsembleLettres remove(final EnsembleLettres param) {
        final String lettresThis = getLettres();
        final String lettresParam = param.getLettres();
        final char[] result = new char[length()];
        int iThis = 0, iParam = 0, n = 0;
        while (iThis < length() && iParam < param.length()) {
            if (lettresThis.charAt(iThis) == lettresParam.charAt(iParam)) {
                iThis++;
                iParam++;
            } else if (lettresThis.charAt(iThis) < lettresParam.charAt(iParam)) {
                result[n] = lettresThis.charAt(iThis);
                n++;
                iThis++;
            } else {
                iParam++;
            }
        }
        while (iThis < length()) {
            result[n] = lettresThis.charAt(iThis);
            n++;
            iThis++;
        }
        return new EnsembleLettres(new String(Arrays.copyOf(result, n)));
    }

    public boolean contains(final EnsembleLettres param) {
        if (length() < param.length()) {
            return false;
        }
        final String lettresThis = getLettres();
        final String lettresParam = param.getLettres();

        int iThis = 0, iParam = 0;
        while (iThis < this.length() && iParam < param.length()) {
            if (lettresThis.charAt(iThis) == lettresParam.charAt(iParam)) {
                iThis++;
                iParam++;
            } else if (lettresThis.charAt(iThis) < lettresParam.charAt(iParam)) {
                iThis++;
            } else {
                return false;
            }
        }
        return iParam == param.length();
    }

    public Optional<EnsembleLettres> complement(final EnsembleLettres param) {
        if (!this.contains(param)) {
            return Optional.empty();
        }
        return Optional.of(this.remove(param));
    }

    @Override
    public int hashCode(){
        return lettres.hashCode();
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final EnsembleLettres other = (EnsembleLettres) obj;
        return lettres.equals(other.lettres);
    }

    @Override
    public String toString(){
        return lettres;
    }
}
package com.company;

public class Mot {

    private EnsembleLettres lettres;

    private final String mot;

    public Mot(final String mot) {
        this.mot = mot;
    }

    public EnsembleLettres getLettres(){
        if (lettres == null) {
            lettres = new EnsembleLettres(mot);
        }
        return lettres;
    }

    public String getMot(){
        return mot;
    }

    public int length(){
        return mot.length();
    }

    @Override
    public int hashCode(){
        return mot.hashCode();
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Mot other = (Mot) obj;
        return mot.equals(other.mot);
    }

    @Override
    public String toString(){
        return mot;
    }
}
package com.company;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.*;

public class Dico {

    private static final Random random = new Random();

    private final Map<EnsembleLettres, Set<Mot>> mots;

    public Dico(final String fileName) {
        mots = new HashMap<>();
        try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
            stream.forEach(line -> add(new Mot(line)));
        } catch (final IOException e) {
            throw new UncheckedIOException("Impossible de lire " + fileName, e);
        }
    }

    public boolean add(final Mot mot) {
        final EnsembleLettres lettres = mot.getLettres();
        Set<Mot> anagrammes = mots.get(lettres);
        if (anagrammes == null) {
            anagrammes = new HashSet<>();
            mots.put(lettres, anagrammes);
        }
        return anagrammes.add(mot);
    }

    public Stream<Mot> getAllMots(){
        return mots.values().stream().flatMap(Set::stream);
    }

    public Stream<Mot> getAllMotsAvec(final EnsembleLettres lettres) {
        return getAllMots().filter(mot -> lettres.contains(mot.getLettres()));
    }

    public Optional<Mot> getRandomMotAvec(final EnsembleLettres lettres) {
        final List<Mot> liste = getAllMotsAvec(lettres).collect(Collectors.toList());
        if (liste.isEmpty()) {
            return Optional.empty();
        }
        return Optional.of(liste.get(random.nextInt(liste.size())));
    }

    public Map<Mot, Set<Mot>> getCoupleMots(final EnsembleLettres lettres) {
        final Map<Mot, Set<Mot>> result = new HashMap<>();
        getAllMots().forEach(mot1 -> lettres.complement(mot1.getLettres()).ifPresent(complement -> {
            final Set<Mot> mots2 = mots.get(complement);
            if (mots2 != null) {
                result.put(mot1, mots2);
            }
        }));
        return result;
    }

    @Override
    public String toString(){
        return mots.toString();
    }
}
package com.company;

public class Main {
    public static void main(final String[] args) {
        final Dico dico = new Dico("U:/dico.txt");
        System.out.println(dico.getCoupleMots(new EnsembleLettres("bonjour"))); // bon=[jour], jour=[bon]
        System.out.println(dico.getCoupleMots(new EnsembleLettres("radicalisation"))); // {antisocial=[dira, raid], dira=[antisocial], raid=[antisocial]}
    }
}

Remarque : un axe d'amélioration pour obtenir de meilleurs résultats serait de mettre toutes les lettres en minuscules et retirer les accents afin d'obtenir des ensembles de lettres propres.
public EnsembleLettres(final String lettres) {
    final char[] chars = Normalizer.normalize(lettres, Normalizer.Form.NFD).replaceAll("\\W", "").toLowerCase().toCharArray();
    Arrays.sort(chars);
    this.lettres = new String(chars);
}
0
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 1
15 mars 2021 à 23:53
Merci pour ta réponse et tes conseils. Je vais essayer de modifier selon.
A propos de la classe Complement, effectivement j'ai regretté un peu plus tard de l'avoir créé, je trouvais qu'elle n'était pas utile. J'aurais juste dû utiliser la classe Mot.
Par contre pour ceci:
ArrayList<Mot> motsComplements = hashtable.get(ensemble.remove(mot));

je suis censée mettre ça à quel moment ? c'est censé remplacer la ligne 104 de la classe Mot?
List motsEnsembleR = dico.getAllMotsAvec(ensemble.getMot());
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
Modifié le 16 mars 2021 à 09:04
Tout d'abord, il faudrait revoir ce qu'est censé être le "complément" d'un mot.
Pour un cas simple comme "bonjour" où on enlève "bon" il reste "jour" donc ça va.
Pour un cas comme "toto" où on enlève "tata" il reste "oo" mais on n'a pas utilisé "aa" du coup je pense qu'ici le complément n'existe pas.
Dans la classe EnsembleLettres tu peux regarder comment j'ai écrit la méthode complement() qui renvoie un résultat empty() pour indiquer que le complément n'existe pas lorsque le paramètre n'est pas contenu dans this.

Quant à l'usage de ce complément il se trouve dans la classe Dico avec la méthode getCoupleMots (qui correspond à deuxSomme, je l'ai juste renommée). Évidemment je n'ai pas repris hashtable qui n'existe plus, mais directement la méthode getAllMots() que je filtre selon si la méthode de complément renvoie un résultat ou non. Si oui c'est le résultat du complément qui est utilisé pour faire une recherche dans le dictionnaire de tous ses anagrammes.
0
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 1 > KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024
17 mars 2021 à 15:06
Ça marche, merci pour ton aide, ça m'aide beaucoup à continuer.
0