public class SequenzaBinaria {
  //Rappr. oggetti 
  private String seq;
  

  // costruisce l'oggetto SequenzaBinaria da una stringa
  public SequenzaBinaria(String x) {
    seq = x;
  }
  
  // calcola la lunghezza della sequenza
  public int lunghezza() { 
    return lunghezza(seq);
  }
  
  private static int lunghezza(String s) {
    if (s.equals("")) 
      return 0;
    else return 1 + lunghezza(s.substring(1));
  }
    
  public SequenzaBinaria concatena (SequenzaBinaria t) { 
    String s = concatena(seq,t.seq);
    return new SequenzaBinaria(s);
  }


  private static String concatena(String s1, String s2) {
    if (s1.equals(""))
      return s2;
    else {
      String s = concatena(s1.substring(1), s2);
      return s1.substring(0,1) + s;
    }
    
  }    


  // restituisce la posizione del primo carattere c nella sequenza
  // oppure -1 se esso non e' presente
  public int indiceDi (char c) { 
    return indiceDi(seq,c,0);
  }

  private static int indiceDi(String s, char c, int i) {
    if (s.equals("")) return -1;
    else {
      if (s.charAt(0)== c) return i;
      else return indiceDi(s.substring(1), c,i+1);
    }
  }
  
  // verifica se la sequenza e' uguale a t
  public boolean uguale(SequenzaBinaria t) {
    return uguale(seq, t.seq);
  }

  private static boolean uguale(String s1, String s2) {
    if (s1.equals(""))
      return s2.equals("");
    else return s1.charAt(0)==s2.charAt(0) && 
           uguale(s1.substring(1),s2.substring(1));
  }

  
  // verifica se p e' un prefisso della sequenza binaria
  public boolean prefisso (SequenzaBinaria p) {
    return prefisso(seq, p.seq);
  }
  
  private static boolean prefisso(String s1, String s2) {
    if (s1.equals(""))
      return true;
    else return s1.charAt(0)==s2.charAt(0) && 
           prefisso(s1.substring(1),s2.substring(1));
  }

  /*
  // restituisce la lunghezza della sequenza piu' lunga di 
  // caratteri c consecutivi
  public int lungSequenzaMassima (char c) { 
    return lsm(seq,c,0,0);
  }

  private static int lsm(String s, char c, int corr, int max) {
    if (s.equals("")) {
      if (corr > max) max = corr;
      return max;
    }
    else 
      if (s.charAt(0)==c) 
        return lsm(s.substring(1),c,corr+1,max);
    else {
      if (corr > max) max = corr;
      return lsm(s.substring(1),c,0,max);
    }
  }

  */

  public String toString() {
    return seq;
  }






  //Versione alternativa che fa uso di un oggetto Env per mantenere i valori
  //calcolati 
  public int lungSequenzaMassima (char c) { 
    Env e = new Env();
    lsm(seq,c,e);
    return e.max;
  }

  private static void lsm(String s, char c, Env e) {
    if (s.equals("")) {
      e.corr = 0;
      e.max = 0;
    } 
    else {
      lsm(s.substring(1),c,e);
      if (s.charAt(0)==c) 
        e.corr++;
      else {
        if (e.corr > e.max) e.max = e.corr;
        e.corr = 0;
      }
    }
  }

}


class Env {
  public int corr;
  public int max;
}
