Toute la solution dans une archive markov.tar.gz, avec les classes WordReader et Args données.

Voici encore une fois, l’archive bovary.tar.gz qui contient le texte de Madame Bovary divisé en 36 chapitres.

Une fois récupérées les archives, voici comment obtenir un nouveau chapitre de Madame Bovary.

# tar zxf markov.tar.gz
# cd markov
# tar zcf ../bovary.tar.gz
# javac Markov.java
# java Markov

Classe WordList

import java.util.* ;

class WordList {
  String val ;
  WordList next ;

  WordList (String valWordList next) {
    this.val = val ;
    this.next = next ;
  }

  static int length(WordList p) {
    int r = 0 ;
    for ( ; p != null ; p = p.next)
      r++ ;
    return r ;
  }

  static String [] toArray(WordList p) {
    // D'abord allouer le tableau.
    int sz = length(p) ;
    String [] r = new String[sz] ;

    // Puis copier les éléments de la liste dans le tableau.
    for (int k = 0 ; k < sz ; k++) {
      r[k] = p.val  ;
      p = p.next ;
    }
    return r ;
  }

  public String toString() {
    StringBuilder r = new StringBuilder () ;
    r.append(this.val) ;
    for (WordList p = this.next ; p != null ; p = p.next) {
      r.append(" " + p.val) ;
    }
    return r.toString() ;
  }
}

Classe Prefix

class Prefix {
  final static String start = "<START>"end = "<END>"par = "<PAR>" ;

  // Le préfixe est un tableau de n mots.
  String [] t ;

  Prefix(int n) {
    t = new String [n] ;
    for (int k = 0 ; k < n ; k++)
      t[k] = start ;
  }

  // Glissement du préfixe.
  private Prefix(String [] t) {
    this.t = t ;
  }

  Prefix shift(String w) {
    int n = t.length ;
    String [] tt = new String [n] ;
    for (int k = 0 ; k < n-1 ; k++)
      tt[k] = t[k+1] ;
    tt[n-1] = w ;
    return new Prefix(tt) ;
  }

  /*****************/
  /* Redéfinitions */
  /*****************/


  // Pas nécessaire, mais peut aider à mettre le programme au point.
  public String toString() {
    StringBuilder r = new StringBuilder () ;
    int n = t.length ;
    for (int k = 0 ; k < n-1 ; k++) {
      r.append(t[k]) ; r.append(" ") ;
    }
    r.append(t[n-1]) ;
    return r.toString() ;
  }

  // Suffisant en pratique : mélange des hashCode() des mots du préfixe.
  public int hashCode() {
    int r = 0 ;
    for (String s : t) {
      r += 37*r + s.hashCode() ;
    }
    return r ;
  }

  // Égalité structurelle des préfixes.
   public boolean equals(Object o) {
     Prefix op = (Prefixo;
     int n = t.length ;
     for (int k = 0 ; k < n ; k++) {
       if (!t[k].equals(op.t[k])) return false ;
     }
     return true ;
  }
}

Classe Markov

import java.util.* ;

class Markov {


  /****************************/
  /* Construction de la table */
  /****************************/

  static HashMap<Prefix,String []> build(String [] filesint n) {

    // Lire l'entrée, donne une table prefixe -> Liste de n+unième mots
    HashMap<Prefix,WordListt = new  HashMap<Prefix,WordList> () ;


    for (String name : files) {
      WordReader reader = new WordReader (name) ;

      String w ;
      Prefix pref = new Prefix (n) ;
      while ((w = reader.read()) != null) {
        t.put(prefnew WordList (w,t.get(pref))) ;
        pref = pref.shift(w) ;
      }
      t.put(prefnew WordList (Prefix.end,t.get(pref))) ;
    }

    // Transformer la table, prefixe -> tableau de n+unième mots
    HashMap<Prefix,String []> r = new  HashMap<Prefix,String []> () ;
    for (Map.Entry<Prefix,WordListe : t.entrySet()) {
      r.put(e.getKey(),WordList.toArray(e.getValue())) ;
    }
    return r ;
  }

  /************************/
  /* Production du texte  */
  /************************/

  static void chain(HashMap<Prefix,String []> tint n) {
    Prefix p = new Prefix (n) ;
    Random rand = new Random () ;

    for ( ; ; ) {
      String [] ws = t.get(p) ;
      String w = ws[rand.nextInt(ws.length)] ;
      if (w.equals(Prefix.end)) {
        System.out.println() ;
        return ;
      }
      dump(w) ;
      p = p.shift(w) ;
    }
  }

  /****************************************************************/
  /* Affichage pas trop moche (et conforme au format de l'entrée) */
  /****************************************************************/

  private static boolean fst = true ;

  static void dump(String w) {
    if (w.equals(Prefix.par)) {
      System.out.println() ;
      System.out.print(w) ;
      System.out.println() ;
      fst = true ;
    } else {
      if (!fstSystem.out.print(" ") ;
      System.out.print(w) ;
      fst = false ;
    }
  }

  public static void main (String [] arg) {
    Args a = new Args (arg) ;
    chain(build(a.files,a.prefixLength),a.prefixLength) ;
  }
}

Ce document a été traduit de LATEX par HEVEA