1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| public class Main {
public static void main(String... args) throws Exception {
// On lit chaque ligne du fichier des mots dans une liste.
// On peut directement passer par readAllLines()
// (pas besoin de Stream)
List<String> keywords = Files.readAllLines(Paths.get("test.txt"));
// On lit le fichier content le texte :
try (BufferedReader br = Files.newBufferedReader(Paths.get("corpus.txt"))) {
// On traite le fichier ligne par ligne, via l'API de Stream
// Et on utilise un Collector pour obtenir le résultat :
Map<String, Integer> result = br.lines()
.collect(Collector.of(
HashMap::new, // Supplier
(map, line) -> accumulate(keywords, map, line), // Accumulator
Main::combine) // Combiner
);
// On affiche le résultat
result.forEach((k, v) -> System.out.println(k + " = " + v));
}
}
/**
* Méthode permettant de compléter la map avec le nombre doccurrence des mots.
*
* @param keywords La liste des mots-clef à rechercher.
* @param map La map à compléter.
* @param text Le texte à analyser.
*/
private static void accumulate(Iterable<String> keywords, Map<String, Integer> map, String text) {
// Pour chacun des mots de notre liste :
for (String word : keywords) {
// On compte le nombre d'occurence du mot dans le texte :
int count = scan(text, word);
// Et on ajoute cela dans la Map
// merge() permet de gérer le cas où la Map comporte déjà une valeur.
map.merge(word, count, Integer::sum);
}
}
/**
* Méthode permettant de regrouper les données de deux map en une seule.
*/
private static Map<String, Integer> combine(Map<String, Integer> map1, Map<String, Integer> map2) {
map2.forEach((k, v) -> {
map1.merge(k, v, Integer::sum);
});
return map1;
}
// J'ai copié/collé et un peu adapté le code de la méthode scan() posté plus haut,
// Pour compter le nombre doccurrence d'un mot dans un texte :
private static int scan(String text, String word) {
final int len = word.length();
int startIndex = 0;
int count = 0;
// On recherche l'index de l'occurence suivante du mot :
while ((startIndex = text.indexOf(word, startIndex)) >= 0) {
int endIndex = startIndex + len;
// On vérifie que le caractère précédent ne soit pas une lettre :
boolean prevCharIsOK = (startIndex == 0)
|| !Character.isLetter(text.charAt(startIndex - 1));
// On vérifie que le caractère suivant ne soit pas une lettre :
boolean nextCharIsOK = (endIndex == text.length())
|| !Character.isLetter(text.charAt(endIndex));
// Si les caractères précédent et suivant sont correct :
if (prevCharIsOK && nextCharIsOK) {
// on incrémente le compteur :
count++;
}
// puis on incrémente l'index pour passer à la suite :
startIndex += len;
}
return count;
}
} |
Partager