import java.io.File; import java.io.FileNotFoundException; import java.util.Collection; import java.util.HashMap; import java.util.Scanner; import java.util.Vector; /* génération d'un texte aléatoire avec des chaînes de Markov * * utilisation: java Markov fichier n * où n est le nombre de mots du texte généré */ /* les clés sont des paires de String */ class StringPair { String fst, snd; StringPair(String fst, String snd) { this.fst = fst; this.snd = snd; } @Override // signifie une redéfinition public int hashCode() { return fst.hashCode() + snd.hashCode(); } @Override public boolean equals(Object o) { StringPair p = (StringPair) o; return this.fst.equals(p.fst) && this.snd.equals(p.snd); } } public class MarkovChains { // les triplets de mots consécutifs sont stockés dans une table static HashMap<StringPair, Vector<String>> chains = new HashMap<StringPair, Vector<String>>(); // tirage aléatoire d'un élément dans une collection c static <E> E randomElement(Collection<E> c) { int n = (int) (Math.random() * c.size()); for (E x : c) if (n-- == 0) return x; assert false; // ne doit pas arriver return null; } // tirage aléatoire dans un vecteur (plus simple) // ici on sait que v contient au moins un élément static String randomElement(Vector<String> v) { assert v.size() > 0; int n = (int) (Math.random() * v.size()); return v.get(n); } // lecture du fichier (suppose qu'il contient au moins deux mots) static void readFile(String file) throws FileNotFoundException { Scanner sc = new Scanner(new File(file)); String w1 = sc.next(); String w2 = sc.next(); StringPair p = new StringPair(w1, w2); while (sc.hasNext()) { String w3 = sc.next(); Vector<String> l = chains.get(p); if (l == null) chains.put(p, l = new Vector<String>()); l.add(w3); p = new StringPair(p.snd, w3); } sc.close(); } /* génération du texte * note : on fait un effort pour ne pas écrire des lignes trop longues */ static void generateText(StringPair p, int words) { System.out.print(p.fst + " " + p.snd + " "); words -= 2; int column = p.fst.length() + p.snd.length() + 2; while (words-- > 0) { Vector<String> l = chains.get(p); if (l == null) return; // vraiment pas de chance String s = randomElement(l); System.out.print(s + " "); column += s.length() + 1; if (column > 70) { System.out.println(); column = 0; } p = new StringPair(p.snd, s); } } public static void main(String[] args) throws FileNotFoundException { readFile(args[0]); StringPair p = randomElement(chains.keySet()); generateText(p, Integer.parseInt(args[1])); System.out.println(); } }