C# – entrées / sorties et fichiers textes (quelques solutionnaires)

Ce qui suit propose quelques solutionnaires aux exercices proposés dans e_s_texte.html.

Fonction TrouverPlusLongueLigne

Énoncé : écrivez la fonction TrouverPlusLongueLigne() qui trouvera et retournera la ligne la plus longue d'un fichier texte. S'il y a plusieurs lignes de cette longueur, retournez n'importe laquelle d'entre elles. Écrivez une version « manuelle » et une version utilisant Split.

Version « manuelle », boucle while :

// ...
static string TrouverPlusLongueLigne(string nomFichier)
{
   string plusseLongue = "";
   using (var lecteur = new StreamReader(nomFichier))
   {
      string ligne = lecteur.ReadLine();
      while (ligne != null)
      {
         if(ligne.Length > plusseLongue.Length)
            plusseLongue = ligne;
         ligne = lecteur.ReadLine();
      }
   }
   return plusseLongue;
}
// ...

Version « manuelle », boucle for :

// ...
static string TrouverPlusLongueLigne(string nomFichier)
{
   string plusseLongue = "";
   using (var lecteur = new StreamReader(nomFichier))
      for(string ligne = lecteur.ReadLine(); ligne != null; ligne = lecteur.ReadLine())
         if(ligne.Length > plusseLongue.Length)
            plusseLongue = ligne;
   return plusseLongue;
}
// ...

Version utilisant Split (présume que lignes.Length > 0) :

// ...
static int PlusseLongue(string s0, string s1) =>
   s1.Length - s0.Length;
static string TrouverPlusLongueLigne(string nomFichier)
{
   using (var lecteur = new StreamReader(nomFichier))
   {
      string[] mots = lecteur.ReadToEnd().Split('\n');
      Array.Sort(mots, PlusseLongue);
      return lignes[0];
   }
}
// ...

Fonction TrouverPlusLongMot

Énoncé : écrivez la fonction TrouverPlusLongMot() qui trouvera et retournera le mot le plus long d'un fichier texte. S'il y a plusieurs mots de cette longueur, retournez n'importe laquelle d'entre elles. Écrivez une version « manuelle » et une version utilisant Split.

Version « manuelle », boucle while :

// ...
static string TrouverPlusLongMot(string nomFichier)
{
   string plusseLong = "";
   string motCourant = "";
   using (var lecteur = new StreamReader(nomFichier))
   {
      bool dansMot = false;
      int c = lecteur.Read();
      while(c != -1)
      {
         if (dansMot && char.IsWhiteSpace((char)c))
         {
            dansMot = false;
            if (motCourant.Length > plusseLong.Length)
               plusseLong = motCourant;
            motCourant = "";
         }
         else if (!dansMot && !char.IsWhiteSpace((char)c))
            dansMot = true;
         if(dansMot)
            motCourant += (char)c;
         c = lecteur.Read();
      }
   }
   return plusseLong;
}
// ...

Version « manuelle », boucle for :

// ...
static string TrouverPlusLongMot(string nomFichier)
{
   string plusseLong = "";
   using (var lecteur = new StreamReader(nomFichier))
   {
      bool dansMot = false;
      string motCourant = "";
      for (int c = lecteur.Read(); c != -1; c = lecteur.Read())
      {
         if (dansMot && char.IsWhiteSpace((char)c))
         {
            dansMot = false;
            if (motCourant.Length > plusseLong.Length)
               plusseLong = motCourant;
            motCourant = "";
         }
         else if (!dansMot && !char.IsWhiteSpace((char)c))
            dansMot = true;
         if(dansMot)
            motCourant += (char)c;
      }
   }
   return plusseLong;
}
// ...

Version utilisant Split :

// ...
static int PlusseLongue(string s0, string s1) =>
   s1.Length - s0.Length;
static string TrouverPlusLongMot(string nomFichier)
{
   using (var lecteur = new StreamReader(nomFichier))
   {
      string[] mots = lecteur.ReadToEnd().Split(null);
      Array.Sort(mots, PlusseLongue);
      return mots[0];
   }
}
// ...

Fonction TrouverMotPlusVoyelleux

Énoncé : écrivez la fonction TrouverMotPlusVoyelleux() qui trouvera et retournera le mot contenant le plus de voyelles d'un fichier texte. S'il y a plusieurs mots avec le même nombre de voyelles, retournez n'importe lequel d'entre eux. Écrivez une version « manuelle » et une version utilisant Split.

Version « manuelle », boucle while :

// ...
static bool EstVoyelle(char c) // pas optimisé
{
   char [] voyelles = new char[]{ 'a', 'e', 'i', 'o', 'u', 'y' };
   c = char.ToLower(c);
   foreach(char v in voyelles)
      if (v == c)
         return true;
   return false;
}
static int CompterVoyelles(string s)
{
   int n = 0;
   foreach(char c in s)
      if (EstVoyelle(c))
         ++n;
   return n;
}
static string TrouverMotPlusVoyelleux(string nomFichier) // pas optimisé
{
   string plusseVoyelleux = "";
   string motCourant = "";
   using (var lecteur = new StreamReader(nomFichier))
   {
      bool dansMot = false;
      int c = lecteur.Read();
      while(c != -1)
      {
         if (dansMot && char.IsWhiteSpace((char)c))
         {
            dansMot = false;
            if (CompterVoyelles(motCourant) > CompterVoyelles(plusseVoyelleux))
               plusseVoyelleux = motCourant;
            motCourant = "";
         }
         else if (!dansMot && !char.IsWhiteSpace((char)c))
            dansMot = true;
         if(dansMot)
            motCourant += (char)c;
         c = lecteur.Read();
      }
   }
   return plusseVoyelleux;
}
// ...

Version « manuelle », boucle for :

// ...
static bool EstVoyelle(char c) // pas optimisé
{
   char [] voyelles = new char[]{ 'a', 'e', 'i', 'o', 'u', 'y' };
   c = char.ToLower(c);
   foreach(char v in voyelles)
      if (v == c)
         return true;
   return false;
}
static int CompterVoyelles(string s)
{
   int n = 0;
   foreach(char c in s)
      if (EstVoyelle(c))
         ++n;
   return n;
}
static string TrouverMotPlusVoyelleux(string nomFichier) // pas optimisé
{
   string plusseVoyelleux = "";
   using (var lecteur = new StreamReader(nomFichier))
   {
      string motCourant = "";
      bool dansMot = false;
      for(int c = lecteur.Read(); c != -1; c = lecteur.Read())
      {
         if (dansMot && char.IsWhiteSpace((char)c))
         {
            dansMot = false;
            if (CompterVoyelles(motCourant) > CompterVoyelles(plusseVoyelleux))
               plusseVoyelleux = motCourant;
            motCourant = "";
         }
         else if (!dansMot && !char.IsWhiteSpace((char)c))
            dansMot = true;
         if(dansMot)
            motCourant += (char)c;
      }
   }
   return plusseVoyelleux;
}
// ...

Version utilisant Split :

// ...
static bool EstVoyelle(char c) // pas optimisé
{
   char [] voyelles = new char[]{ 'a', 'e', 'i', 'o', 'u', 'y' };
   c = char.ToLower(c);
   foreach(char v in voyelles)
      if (v == c)
         return true;
   return false;
}
static int CompterVoyelles(string s)
{
   int n = 0;
   foreach(char c in s)
      if (EstVoyelle(c))
         ++n;
   return n;
}
static int ComparateurVoyelles(string s0, string s1) =>
   CompterVoyelles(s1.Length) - CompterVoyelles(s0.Length);
static string TrouverMotPlusVoyelleux(string nomFichier)
{
   using (var lecteur = new StreamReader(nomFichier))
   {
      string[] mots = lecteur.ReadToEnd().Split(null);
      Array.Sort(mots, ComparateurVoyelles);
      return mots[0];
   }
}
// ...

Fonction TrouverMotPlusFréquent

Énoncé : écrivez la fonction TrouverMotPlusFréquent() qui trouvera et retournera le mot apparaissant le plus grand nombre de fois dans un fichier texte. S'il y a plusieurs mots avec le même nombre d'occurrences, retournez n'importe lequel d'entre eux. Écrivez une version « manuelle » et une version utilisant Split.

Ceci est plus difficile, car il faut garder tous les mots et compter le nombre d'occurrences de chacun. Un truc simple (mais naïf et inefficace) serait :

En utilisant Split pour simplifier, ça donnerait quelque chose comme :

// ...
static int CompterNonVides(string [] strs)
{
   int n = 0;
   foreach (string s in strs)
      if (s.Length != 0)
         ++n;
   return n;
}
static int CompterMots(string nomFichier)
{
   using (var lecteur = new StreamReader(nomFichier))
      return CompterNonVides(lecteur.ReadToEnd().Split(null));
}
static void CopierNonVides(string [] dest, string [] src)
{
   int i = 0;
   foreach (string s in src)
      if (s.Length != 0)
         dest[i++] = s;
}
static string TrouverMotPlusFréquent(string nomFichier)
{
   string [] mots = new string[CompterMots(nomFichier)];
   // lire les mots, incluant les vides
   string [] strs;
   using (var lecteur = new StreamReader(nomFichier))
      strs = lecteur.ReadToEnd().Split(null);
   // déposer dans mots chaque mot non-vide
   CopierNonVides(mots, strs);
   // trier les mots pour que les pareils soient côte à côte
   Array.Sort(mots);
   // résultats (éventuels) du calcul
   string motPlusFréquent = "";
   int nbOccurrencesPlusFréquent = 0;
   // suppose que mots.Length > 0
   int débutMotCourant = 0;
   int nbOccurrences = 1;
   for(int i = 1; i < mots.Length; ++i)
   {
      if(mots[i] == mots[débutMotCourant])
         ++nbOccurrences;
      else
      {
         if (nbOccurrences > nbOccurrencesPlusFréquent)
         {
            nbOccurrencesPlusFréquent = nbOccurrences;
            motPlusFréquent = mots[débutMotCourant];
         }
         nbOccurrences = 1;
         débutMotCourant = i;
      }
   }
   // dernier test au cas où la réponse serait à la toute fin
   if (nbOccurrences > nbOccurrencesPlusFréquent)
      motPlusFréquent = mots[débutMotCourant];
   return motPlusFréquent;
}
// ...

Il y a bien sûr des solutions plus simples si on connaît des outils plus sophistiqués.


Valid XHTML 1.0 Transitional

CSS Valide !