package amphis; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Scanner; /* utilisation : java Amphi6b fichier * lit tous les mots du fichier * puis, en boucle, lit un préfixe sur l'entrée standard * et affiche tous les mots ayant ce préfixe */ // les mots sont stockés dans un arbre de préfixes class Trie { private boolean word; private final Map<Character, Trie> branches; Trie() { this.word = false; this.branches = new HashMap<Character, Trie>(); } void add(String s) { Trie t = this; for (int i = 0; i < s.length(); i++) { // invariant t != null char c = s.charAt(i); Map<Character, Trie> b = t.branches; t = b.get(c); if (t == null) { t = new Trie(); b.put(c, t); } } t.word = true; } int size() { int s = 0; if (this.word) s++; for (Trie b: this.branches.values()) s += b.size(); return s; } Collection<String> below(String w) { Collection<String> coll = new LinkedList<>(); Trie t = this; for (int i = 0; i < w.length(); i++) { // t != null t = t.branches.get(w.charAt(i)); if (t == null) return coll; } t.collect(w, coll); return coll; } void collect(String prefix, Collection<String> coll) { if (this.word) coll.add(prefix); for (Character c: this.branches.keySet()) this.branches.get(c).collect(prefix + c, coll); } } public class Amphi6b { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(new File("jules-verne.txt")); sc.useDelimiter("[\\p{javaWhitespace}«»\\p{Punct}]+"); Trie t = new Trie(); while (sc.hasNext()) t.add(sc.next()); sc.close(); System.out.println(t.size() + " mots"); BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); while (true) { String p = r.readLine(); if (p == null) break; Collection<String> c = t.below(p); System.out.println(c.size() + " mots commençant par '" + p + "'"); for (String s : c) System.out.print(s + " "); System.out.println(); } } }