Ce qui suit propose quelques solutionnaires aux exercices proposés dans e_s_texte.html.
É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];
}
}
// ...
É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];
}
}
// ...
É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];
}
}
// ...
É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.