Apprendre les algo – Jour 7
Introduction
Jusqu'ici, vous avez déjà vu :
- les variables
- les conditions
- les boucles
- les tableaux
- les procédures et les fonctions
- les classes
Le moment est donc venu de passer aux exercices.
Ici, nous allons travailler sur une classe Tableau.
Le but est seulement de résoudre des exercices simples et très classiques.
À chaque fois, vous trouverez :
- l'énoncé
- le principe utilisé
- le corrigé
- un appel dans le programme principal
N'hésitez pas à relire le jour 4, le jour 5 et le jour 6 si un point vous semble flou.
Base de départ
Si vous utilisez JetBrains Rider, vous pouvez créer rapidement le projet comme ceci :
FileNew Solution- choisir Console Application
- choisir C#
- donner un nom au projet
- valider
Une fois le projet créé, gardez simplement une structure très simple au début.
Par exemple :
ConsoleApp2/
├── Program.cs
└── Tableau.cs
Ici :
Program.cscontient le programme principalTableau.cscontient la classeTableau
Avant les exercices, voici par exemple ce que vous pouvez mettre dans Tableau.cs :
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
public Tableau()
{
tab = new int[N];
l = 0;
}
}
Ici :
tabcontient les valeurslreprésente le nombre d'éléments réellement utilisésNreprésente la capacité maximale
En langage très simple :
private int[] tab;: c'est la grande boîte qui va contenir les nombresprivate int l;: c'est le nombre de cases vraiment rempliespublic static int N = 100;: c'est la taille maximale du tableau
Il faut bien distinguer l et N :
Ndit combien de places existent au totalldit combien de places sont déjà utilisées
Par exemple, on peut avoir :
N = 10l = 4
Cela veut dire :
- le tableau peut contenir 10 valeurs au maximum
- mais pour l'instant, seulement 4 cases sont vraiment utilisées
Le bloc suivant :
public Tableau()
{
tab = new int[N];
l = 0;
}
s'appelle un constructeur.
Pour faire très simple, c'est un morceau de code qui prépare l'objet au moment où on le crée.
Ici, il sert juste à initialiser les attributs :
tab = new int[N];: on fabrique un tableau vide de tailleNl = 0;: on dit qu'au début, aucune case n'est utilisée
On peut le voir comme ceci :
- on prépare l'armoire
- on fixe le nombre total de cases
- puis on dit qu'au départ, elle est vide
Exercice 1. estVide()
Énoncé
Écrire une méthode qui dit si le tableau est vide.
Principe
On utilise ici une idée très simple :
Vous avez compris que l est censé contenir le nombre d'éléments réellement présents dans le tableau.
Donc, si on veut savoir si le tableau est vide, c'est très simple :
- s'il n'y a aucun élément, alors
lvaut0 - donc il suffit de vérifier si
l == 0
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public bool estVide()
{
return l == 0;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
Console.WriteLine(tableau.estVide());
}
}
Exercice 2. estTrie()
Énoncé
Écrire une méthode qui dit si le tableau est trié dans l'ordre croissant.
Principe
On utilise ici le schéma de parcours vu au jour 4 :
- on compare chaque case avec la suivante
- dès qu'on trouve une paire mal ordonnée, on répond
false
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public bool estTrie()
{
int i = 0;
while (i < l - 1)
{
if (tab[i] > tab[i + 1])
{
return false;
}
i++;
}
return true;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(3);
tableau.ajouterElement(8);
tableau.ajouterElement(12);
Console.WriteLine(tableau.estTrie());
}
}
Exercice 3. ajouterElement(int element)
Énoncé
Ajouter un élément à la fin du tableau.
Principe
On place la nouvelle valeur à la position l, puis on augmente l.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void ajouterElement(int element)
{
tab[l] = element;
l = l + 1;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
}
}
Exercice 4. afficher()
Énoncé
Afficher tous les éléments du tableau.
Principe
On utilise le schéma de parcours :
- on part du début
- on affiche chaque case
- on avance avec
i
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void afficher()
{
int i = 0;
while (i != l)
{
Console.Write("[" + tab[i] + "]");
i++;
}
Console.WriteLine();
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.afficher();
}
}
Exercice 5. sommeMoyenne()
Énoncé
Calculer puis afficher la somme et la moyenne des éléments.
Principe
On utilise encore le schéma de parcours :
- on additionne tous les éléments
- puis on divise la somme par la taille
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void sommeMoyenne()
{
if (estVide())
{
Console.WriteLine("Tableau vide");
return;
}
int i = 0;
int som = 0;
while (i != l)
{
som += tab[i];
i++;
}
float moy = (float)som / l;
Console.WriteLine("La somme est : " + som);
Console.WriteLine("La moyenne est : " + moy);
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(10);
tableau.ajouterElement(30);
tableau.sommeMoyenne();
}
}
Exercice 6. estPresent(int element)
Énoncé
Dire si un élément est présent dans le tableau.
Principe
On utilise le schéma de recherche vu au jour 4 :
- on avance tant qu'on n'a pas trouvé
- ou tant qu'on n'est pas arrivé à la fin
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public bool estPresent(int element)
{
int i = 0;
while (i != l && tab[i] != element)
{
i++;
}
return i != l;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
Console.WriteLine(tableau.estPresent(200));
}
}
Exercice 7. nbOccurence(int element)
Énoncé
Compter combien de fois un élément apparaît dans le tableau.
Principe
On parcourt tout le tableau :
- si l'élément courant est égal à la valeur cherchée
- on augmente le compteur
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public int nbOccurence(int element)
{
int i = 0;
int cpt = 0;
while (i != l)
{
if (tab[i] == element)
{
cpt = cpt + 1;
}
i++;
}
return cpt;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(20);
Console.WriteLine("NB occ de 20 : " + tableau.nbOccurence(20));
}
}
Exercice 8. positionPremierOcc(int element)
Énoncé
Trouver la position de la première occurrence d'un élément.
Principe
On réutilise le schéma de recherche :
- si on trouve, on retourne l'indice
- sinon, on retourne
-1
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public int positionPremierOcc(int element)
{
int i = 0;
while (i != l && tab[i] != element)
{
i++;
}
if (i != l)
{
return i;
}
return -1;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
Console.WriteLine("Position premier occ de 10 : " + tableau.positionPremierOcc(10));
}
}
Exercice 9. min()
Énoncé
Trouver le plus petit élément du tableau.
Principe
On suppose au départ que le minimum est le premier élément, puis on compare avec tous les autres.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public int min()
{
if (estVide())
{
// On arrête ici, car on ne peut pas chercher un minimum dans un tableau vide.
throw new Exception("Tableau vide");
}
int i = 1;
int min = tab[0];
while (i != l)
{
if (tab[i] < min)
{
min = tab[i];
}
i++;
}
return min;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
Console.WriteLine(tableau.min());
}
}
Exercice 10. max()
Énoncé
Trouver le plus grand élément du tableau.
Principe
Même idée que pour le minimum, mais avec la comparaison inverse.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public int max()
{
if (estVide())
{
// On arrête ici, car on ne peut pas chercher un maximum dans un tableau vide.
throw new Exception("Tableau vide");
}
int i = 1;
int max = tab[0];
while (i != l)
{
if (tab[i] > max)
{
max = tab[i];
}
i++;
}
return max;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(100);
Console.WriteLine(tableau.max());
}
}
Exercice 11. trier()
Énoncé
Trier le tableau dans l'ordre croissant.
Principe
On utilise ici un tri très simple :
- on fixe une case
- on la compare aux suivantes
- on échange si besoin
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void trier()
{
int i = 0;
while (i != l - 1)
{
int j = i + 1;
while (j != l)
{
if (tab[i] > tab[j])
{
int stock = tab[i];
tab[i] = tab[j];
tab[j] = stock;
}
j++;
}
i++;
}
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
tableau.trier();
tableau.afficher();
}
}
Exercice 12. inverser()
Énoncé
Inverser le tableau.
Principe
On échange :
- le début avec la fin
- puis le deuxième avec l'avant-dernier
- et ainsi de suite
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void inverser()
{
int i = 0;
int j = l - 1;
while (i < j)
{
int stock = tab[i];
tab[i] = tab[j];
tab[j] = stock;
i++;
j--;
}
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
tableau.inverser();
tableau.afficher();
}
}
Exercice 13. insererOrdonner(int element)
Énoncé
Insérer un élément dans un tableau tout en gardant l'ordre croissant.
Principe
On trie d'abord si besoin, puis :
- on décale vers la droite les éléments plus grands
- on place la nouvelle valeur au bon endroit
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void insererOrdonner(int element)
{
if (!estTrie())
{
// On trie d'abord, sinon on ne peut pas garantir une insertion au bon endroit.
trier();
}
int i = l - 1;
while (i != -1 && tab[i] >= element)
{
tab[i + 1] = tab[i];
i = i - 1;
}
tab[i + 1] = element;
l = l + 1;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
tableau.insererOrdonner(15);
tableau.afficher();
}
}
Exercice 14. supprimerDansUnePostion(int k)
Énoncé
Supprimer l'élément situé à une position donnée.
Principe
On décale vers la gauche tous les éléments qui suivent cette position.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void supprimerDansUnePostion(int k)
{
int i = k;
while (i < l - 1)
{
tab[i] = tab[i + 1];
i++;
}
l = l - 1;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
tableau.ajouterElement(100);
tableau.supprimerDansUnePostion(2);
tableau.afficher();
}
}
Exercice 15. supprimerNonOrdonnerAPosition(int k)
Énoncé
Supprimer rapidement un élément à une position donnée, sans se soucier de garder l'ordre.
Principe
On remplace la case à supprimer par le dernier élément du tableau.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void supprimerNonOrdonnerAPosition(int k)
{
tab[k] = tab[l - 1];
l = l - 1;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
tableau.ajouterElement(100);
tableau.supprimerNonOrdonnerAPosition(1);
tableau.afficher();
}
}
Exercice 16. suppressionElement(int element)
Énoncé
Supprimer un élément par sa valeur.
Principe
On cherche d'abord sa position, puis on réutilise la suppression par position.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public void suppressionElement(int element)
{
int i = 0;
while (i != l && tab[i] != element)
{
i++;
}
if (i != l)
{
supprimerDansUnePostion(i);
}
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
tableau.ajouterElement(10);
tableau.suppressionElement(9);
tableau.afficher();
}
}
Exercice 17. taille()
Énoncé
Retourner le nombre d'éléments réellement présents dans le tableau.
Principe
Ici, la taille utile est déjà stockée dans l.
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public int taille()
{
return l;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(20);
tableau.ajouterElement(9);
Console.WriteLine(tableau.taille());
}
}
Exercice 18. getElement(int index) et setElement(int index, int valeur)
Énoncé
Lire ou modifier un élément à une position donnée.
Principe
getElementretourne la valeursetElementremplace la valeur
Corrigé
namespace ConsoleApp2;
public class Tableau
{
private int[] tab;
private int l;
public static int N = 100;
...
public int getElement(int index)
{
if (estVide())
{
// On arrête ici, car il n'y a aucun élément à lire dans un tableau vide.
throw new Exception("Tableau vide");
}
return tab[index];
}
public void setElement(int index, int valeur)
{
tab[index] = valeur;
}
}
Appel dans le programme principal
using ConsoleApp2;
public class Program
{
public static void Main()
{
Tableau tableau = new Tableau();
tableau.ajouterElement(10);
tableau.ajouterElement(9);
Console.WriteLine(tableau.getElement(0));
tableau.setElement(0, 20);
tableau.afficher();
}
}
Fin du jour 7
À ce stade, vous avez déjà manipulé beaucoup d'exercices classiques sur les tableaux :
- test
- recherche
- parcours
- minimum et maximum
- tri
- suppression
- insertion
Prenez le temps de relire plusieurs fois. Quand on débute, refaire les mêmes exercices aide énormément.
Le plus important maintenant est de reconnaître le bon schéma :
- parcours
- recherche
- décalage
- échange
Autrement dit, dans beaucoup d'exercices, il ne faut pas trop paniquer ni trop compliquer les choses.
Prenez l'habitude de :
- lire l'énoncé 3 fois calmement
- vous demander ce que l'on cherche vraiment
Puis posez-vous cette question très simple :
- est-ce qu'il faut connaître toutes les valeurs du tableau ?
- ou est-ce qu'il faut seulement trouver une valeur ou une position ?
Si vous avez besoin de lire tout le tableau, pensez d'abord au schéma de parcours. Si vous cherchez seulement un élément précis, pensez d'abord au schéma de recherche.
Nous l'avons déjà vu au jour 4, mais il faut vraiment garder ce réflexe en tête :
- parcours quand on lit tout
- recherche quand on cherche quelque chose
- décalage quand on insère ou supprime
- échange quand on inverse ou quand on trie