Fonction : où réinitialiser le compteur
Résolu/Fermé
charline159
Messages postés
208
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
22 juin 2022
-
Modifié le 17 févr. 2021 à 02:24
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 - 18 févr. 2021 à 14:58
charline159 Messages postés 208 Date d'inscription lundi 14 août 2017 Statut Membre Dernière intervention 22 juin 2022 - 18 févr. 2021 à 14:58
A voir également:
- Fonction : où réinitialiser le compteur
- Fonction si et - Guide
- Fonction moyenne excel - Guide
- Fonction somme excel - Guide
- Fonction remplacer word - Guide
- Excel renvoyer la valeur d'une cellule en fonction d'une autre - Forum Logiciels
5 réponses
KX
Messages postés
16752
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 août 2024
3 019
17 févr. 2021 à 10:26
17 févr. 2021 à 10:26
Bonjour,
Tel que tu l'as imaginé, le programme ne fonctionnera pas, tu ne peux pas choisir un mot au hasard et espérer qu'il respecte les contraintes. Imaginons que ton ensemble en paramètre ne corresponde à aucun mot, cela signifie que ta boucle va tourner indéfiniment, en analysant plusieurs fois le même mot, voire tous les mots à terme, mais tu continueras quand même.
Il faut tout reprendre de zéro. Et c'est l'occasion de se lancer sur de la programmation objet, car l'exercice s'y prête bien.
Déjà, il faut prendre en considération ce que j'ai pu te dire dans ta discussion précédente, pour avoir un algorithme efficace : il faut travailler sur des lettres triées, cela évite d'avoir une double boucle for quand une seule suffit.
Exemple complet :
Tel que tu l'as imaginé, le programme ne fonctionnera pas, tu ne peux pas choisir un mot au hasard et espérer qu'il respecte les contraintes. Imaginons que ton ensemble en paramètre ne corresponde à aucun mot, cela signifie que ta boucle va tourner indéfiniment, en analysant plusieurs fois le même mot, voire tous les mots à terme, mais tu continueras quand même.
Il faut tout reprendre de zéro. Et c'est l'occasion de se lancer sur de la programmation objet, car l'exercice s'y prête bien.
Déjà, il faut prendre en considération ce que j'ai pu te dire dans ta discussion précédente, pour avoir un algorithme efficace : il faut travailler sur des lettres triées, cela évite d'avoir une double boucle for quand une seule suffit.
Exemple complet :
import java.util.Arrays; public class MotDico { private final String mot; private String lettresTriees; public MotDico(String mot) { this.mot = mot; } public String getMot(){ return mot; } public String getLettresTriees(){ if (lettresTriees == null) { char[] lettres = mot.toCharArray(); Arrays.sort(lettres); lettresTriees = new String(lettres); } return lettresTriees; } public int length(){ return mot.length(); } public boolean contains(MotDico mot2) { if (length() < mot2.length()) return false; String lettres = getLettresTriees(); String lettres2 = mot2.getLettresTriees(); int i = 0, i2 = 0; while (i < length() && i2 < mot2.length()) { if (lettres.charAt(i) == lettres2.charAt(i2)) { i++; i2++; } else if (lettres.charAt(i) < lettres2.charAt(i2)) { i++; } else { return false; } } return i2 == mot2.length(); } @Override public String toString(){ return mot; } }
import java.io.*; import java.nio.file.*; import java.util.*; public class Dico { private static final Random random = new Random(); private final List<MotDico> mots; public Dico(String fileName) { mots = new ArrayList<>(); try { for (String line : Files.readAllLines(Paths.get(fileName))) { mots.add(new MotDico(line)); } } catch (IOException e) { throw new UncheckedIOException("Impossible de lire " + fileName, e); } } public List<MotDico> getAllMots(){ return Collections.unmodifiableList(mots); } public List<MotDico> getAllMotsAvec(String lettres) { MotDico ensemble = new MotDico(lettres); List<MotDico> result = new ArrayList<>(); for (MotDico mot : mots) { if (ensemble.contains(mot)) { result.add(mot); } } return Collections.unmodifiableList(result); } public MotDico getRandomMotAvec(String lettres) { List<MotDico> liste = getAllMotsAvec(lettres); if (liste.isEmpty()) return null; return liste.get(random.nextInt(liste.size())); } }
public class TestDico { public static void main(String[] args) { MotDico jour = new MotDico("jour"); System.out.println(jour.contains(jour)); // true MotDico bonjour = new MotDico("bonjour"); System.out.println(bonjour.contains(jour)); // true System.out.println(jour.contains(bonjour)); // false MotDico matin = new MotDico("matin"); System.out.println(jour.contains(matin)); // false System.out.println(matin.contains(jour)); // false Dico dico = new Dico("E:/mots.txt"); System.out.println(dico.getAllMotsAvec("bonjour")); // bon, jour, bonjour, juron, ... System.out.println(dico.getRandomMotAvec("bonjour")); // brun } }
charline159
Messages postés
208
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
22 juin 2022
1
Modifié le 17 févr. 2021 à 16:51
Modifié le 17 févr. 2021 à 16:51
D'accord, merci. Par contre quand j'ai essayé TestDico, j'ai eu toutes ces erreurs:
pourtant j'ai bien mis le chemin exact où se trouve mon fichier avec
dans la fonction de test, mais ça ne change rien...
Exception in thread "main" java.io.UncheckedIOException: Impossible de lire E:/mots.txt at com.company.Dico.<init>(Dico.java:20) at com.company.Dico.main(Dico.java:63) Caused by: java.nio.file.NoSuchFileException: E:\mots.txt at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85) at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103) at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108) at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:235) at java.base/java.nio.file.Files.newByteChannel(Files.java:375) at java.base/java.nio.file.Files.newByteChannel(Files.java:426) at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420) at java.base/java.nio.file.Files.newInputStream(Files.java:160) at java.base/java.nio.file.Files.newBufferedReader(Files.java:2916) at java.base/java.nio.file.Files.readAllLines(Files.java:3396) at java.base/java.nio.file.Files.readAllLines(Files.java:3436) at com.company.Dico.<init>(Dico.java:16) ... 1 more
pourtant j'ai bien mis le chemin exact où se trouve mon fichier avec
Dico dico = new Dico("C:\\Users\\Slash\\IdeaProjects\\2-somme\\src\\com\\company\\mots.txt");
dans la fonction de test, mais ça ne change rien...
KX
Messages postés
16752
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 août 2024
3 019
17 févr. 2021 à 17:16
17 févr. 2021 à 17:16
Le message d'erreur référence toujours "E:\mots.txt" donc c'est que la classe de test n'a pas été recompilé avant d'être exécuté, c'est toujours ma version du code qui est pris en compte.
charline159
Messages postés
208
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
22 juin 2022
1
17 févr. 2021 à 17:42
17 févr. 2021 à 17:42
oui désolée, j'ai oublié de changer les erreurs en conséquence, du coup j'obtiens:
je vois pas quoi faire de plus étant donné que le chemin est déjà correct...
Exception in thread "main" java.io.UncheckedIOException: Impossible de lire C:\Users\Slash\IdeaProjects\2-somme\src\com\company\mots.txt at com.company.Dico.<init>(Dico.java:21) at com.company.Dico.main(Dico.java:71) Caused by: java.nio.file.NoSuchFileException: C:\Users\Slash\IdeaProjects\2-somme\src\com\company\mots.txt at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85) at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103) at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108) at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:235) at java.base/java.nio.file.Files.newByteChannel(Files.java:375) at java.base/java.nio.file.Files.newByteChannel(Files.java:426) at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420) at java.base/java.nio.file.Files.newInputStream(Files.java:160) at java.base/java.nio.file.Files.newBufferedReader(Files.java:2916) at java.base/java.nio.file.Files.readAllLines(Files.java:3396) at java.base/java.nio.file.Files.readAllLines(Files.java:3436) at com.company.Dico.<init>(Dico.java:17) ... 1 more
je vois pas quoi faire de plus étant donné que le chemin est déjà correct...
KX
Messages postés
16752
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 août 2024
3 019
17 févr. 2021 à 18:09
17 févr. 2021 à 18:09
NoSuchFileException signifie que le fichier n'existe pas, c'est probablement le chemin d'accès qui est mal écrit. Tu peux essayer en copiant le fichier dans un autre dossier, par exemple C:/mots.txt
charline159
Messages postés
208
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
22 juin 2022
1
17 févr. 2021 à 19:52
17 févr. 2021 à 19:52
Le nom du fichier n'était pas le bon, autant pour moi... et merci pour ta patience...
J'ai un peu modifié la fonction getRandomMotAvec, afin que le mot soit retourné seulement s'il est contenu dans le dictionnaire.
Par ailleurs, j'ai voulu utilisé cette méthode pour obtenir le complément d'un mot.
Par exemple, avec l'ensemble "bonjour", et le mot "jour", j'obtiens le complément "bno". Elle fonctionne.
Cependant, j'ai essayé de transformer la méthode en non static avec
et en testant avec
mais ça ne marche pas parce que complement n'a pas été initialisé, mais c'est de cette manière que j'aimerais l'initaliser justement.
Qu'est-ce que je devrais modifier pour que la méthode marche en non static ?
J'ai un peu modifié la fonction getRandomMotAvec, afin que le mot soit retourné seulement s'il est contenu dans le dictionnaire.
Par ailleurs, j'ai voulu utilisé cette méthode pour obtenir le complément d'un mot.
Par exemple, avec l'ensemble "bonjour", et le mot "jour", j'obtiens le complément "bno". Elle fonctionne.
static String getComplement(String ensemble, String mot){ String complement = ensemble; for(char c:mot.toCharArray()){ // supprime la lettre (dans ensemble) équivalente à la lettre c (dans mot) complement=complement.replaceFirst(""+c, ""); } return complement; }
Cependant, j'ai essayé de transformer la méthode en non static avec
public String getComplement2(String ensemble, String mot){ String complement = ensemble; for(char c:mot.toCharArray()){ // supprime la lettre (dans ensemble) équivalente à la lettre c (dans mot) complement=complement.replaceFirst(""+c, ""); } return complement; }
et en testant avec
String complement = complement.getComplement2();
mais ça ne marche pas parce que complement n'a pas été initialisé, mais c'est de cette manière que j'aimerais l'initaliser justement.
Qu'est-ce que je devrais modifier pour que la méthode marche en non static ?
KX
Messages postés
16752
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 août 2024
3 019
18 févr. 2021 à 08:38
18 févr. 2021 à 08:38
"J'ai un peu modifié la fonction getRandomMotAvec, afin que le mot soit retourné seulement s'il est contenu dans le dictionnaire."
Je ne comprends pas ce que tu veux dire, le mot retourné est forcément contenu dans le dictionnaire, d'où est-ce qu'il viendrait sinon ?
Quant à ton complément, on en revient à ce qui a déjà été dit, il faut travailler avec les char[] plutôt qu'avec des String, et avec les lettres triées c'est plus efficace, donc utiliser un MotDico plutôt qu'un String.
Dans la classe MotDico :
Ce qui donne dans TestDico :
Je ne comprends pas ce que tu veux dire, le mot retourné est forcément contenu dans le dictionnaire, d'où est-ce qu'il viendrait sinon ?
Quant à ton complément, on en revient à ce qui a déjà été dit, il faut travailler avec les char[] plutôt qu'avec des String, et avec les lettres triées c'est plus efficace, donc utiliser un MotDico plutôt qu'un String.
Dans la classe MotDico :
public String remove(MotDico mot2) { String lettres = getLettresTriees(); String lettres2 = mot2.getLettresTriees(); char[] result = new char[length()]; int i = 0, i2 = 0, n = 0; while (i < length() && i2 < mot2.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)); }
Ce qui donne dans TestDico :
System.out.println(bonjour.remove(jour)); // bno System.out.println(bonjour.remove(matin)); // bjooru System.out.println(matin.remove(bonjour)); // aimt
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
charline159
Messages postés
208
Date d'inscription
lundi 14 août 2017
Statut
Membre
Dernière intervention
22 juin 2022
1
18 févr. 2021 à 12:23
18 févr. 2021 à 12:23
Je pensais qu'il y avait des mots qui n'appartenaient pas au dictionnaire étant donné qu'il y avait des mots un peu curieux, comme "ru" ou "no", mais effectivement ils font bien partis du dictionnaire.
Pour la méthode remove, je viens d'essayer et ça marche bien effectivement, merci une fois de plus.
J'aimerais faire une méthode qui automatise tout de A à Z pour obtenir le complément d'un mot, c'est-à-dire que cette méthode prend tout en paramètre (dictionnaire, ensemble, mot) dès le début pour renvoyer directement le complément (au lieu de le faire "manuellement, étape par étape" en dehors d'une fonction).
Si je place cette méthode dans la classe MotDico, ça reste cohérent ? (Etant donné que ça va faire appel à une méthode de la classe Dico.)
Pour la méthode remove, je viens d'essayer et ça marche bien effectivement, merci une fois de plus.
J'aimerais faire une méthode qui automatise tout de A à Z pour obtenir le complément d'un mot, c'est-à-dire que cette méthode prend tout en paramètre (dictionnaire, ensemble, mot) dès le début pour renvoyer directement le complément (au lieu de le faire "manuellement, étape par étape" en dehors d'une fonction).
Si je place cette méthode dans la classe MotDico, ça reste cohérent ? (Etant donné que ça va faire appel à une méthode de la classe Dico.)
KX
Messages postés
16752
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 août 2024
3 019
18 févr. 2021 à 13:43
18 févr. 2021 à 13:43
Non, la classe Dico manipule des MotDico, mais pas l'inverse.
Il vaut mieux faire ton code dans une classe à part, un peu comme le fait TestDico.
Il vaut mieux faire ton code dans une classe à part, un peu comme le fait TestDico.
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
16752
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
31 août 2024
18 févr. 2021 à 14:58
18 févr. 2021 à 14:58
d'accord, je vais faire ça alors, merci pour ton aide une fois de plus !