Correction Sujets de TD n 1 et n 2 UEO12 UEO12 TD1 Question n 1 : Exercice sur les tableaux à une dimension : écrire un programme permettant de calculer la somme pondérée suivante : dim tab i 1 tab [i] i=0 Pour réaliser cette exercice, on suppose que le tableau tab est déclaré de la façon suivante : int tab[5]=3,4,8,0,2; Correction Nous avons ici à calculer pour chaque valeur de i l'expression (i+1)*tab[i]. Nous sommes donc ici en présence d'une instruction que nous devons répéter un nombre connu et fini de fois. Il est donc préférable d'utiliser une boucle for. Dans cette boucle, nous réaliserons le calcul (i+1)*tab[i]. Cependant, il nous faut stocker et accumuler le résultat de ce calcul pour chaque valeur de i, vu qu'il nous est demandé de réaliser la somme. Nous devrons donc utiliser une variable somme que nous initialiserons en dehors de la boucle et à laquelle nous ajouterons, à chaque tour de boucle, le résultat du calcul (i+1)*tab[i]. Si l'on récapitule l'on a 3 variables : le tableau tab (entiers), l'indice i (entier) et la somme (entier) 1 boucle for faisant i aller de 0 à 5 (ici dimtab=5) 1 affichage à réaliser à la fin. Donc au final, la proposition de code suivante : int main(void)
int tab[5]=3,4,8,0,2; int i, somme; //Initialisation de la somme somme=0; //Calcul de la somme for(i=0;i<5;i++) somme = somme + (i+1)*tab[i]; //Affichage à la fin du calcul printf(«la somme pondérée est :%d\n»,somme); Question n 2 : Soit une image en niveau de gris de 10 pixels par 10 pixels. Cette image est représentée en machine par une matrice de 10 X 10 de unsigned char. La valeur de chaque pixel est comprise entre 0 (noir) et 255 (blanc). L'on souhaite afficher un seuillage de cette image permettant de mettre en valeur les régions les plus claires. Ce seuillage consiste à afficher une à une chaque case de la matrice en affichant «X» si la valeur de la case est supérieure à 120 et «.» si ce n'est pas le cas. Ecrire le programme permettant de réaliser ce traitement, en supposant que la matrice est déjà remplie. Exemple : Matrice en machine Affichage à l'écran 4 7 130 140.. X X 34 140 120 200. X. X 7 32 120 199... X 2 4 4 4....
Correction Dans cet exercice, nous n'avons à réaliser que de l'affichage. Cependant, cet affichage diffère suivant que la valeur de la case à afficher dépasse ou non un certain seuil. Il faudra donc prendre en compte cette condition lorsque nous allons construire le code. Autre difficulté, chaque ligne devra se situer à l'emplacement exact de la ligne correspondante dans la matrice pour ainsi visualiser l'emplacement exact des valeurs recherchées dans la matrice de départ. Donc, si l'on considère la forme de notre matrice, il faudra deux boucles imbriquées (nombre d'itérations connu => boucle for) pour afficher la matrice, la boucle la plus intérieure parcourant les colonnes et la boucle extérieure les lignes. Il faudra donc, à la fin de la boucle intérieure prévoir un retour à la ligne. On arrive à la proposition de correction suivante : int main(void) unsigned char ima[10][10]; int i,j; //On suppose que la matrice est remplie //Seuillage //Pour chaque ligne for(i=0; i<10; i++) //Pour chaque valeur de la ligne for(j=0;j<10;j++) //On réalise l'affichage du seuillage if((int)(ima[i][j]) > 120) printf(«x»); else printf(«.»); //A la fin de chaque ligne, retour à la ligne printf(«\n»); Remarque : Pour réaliser la comparaison, on utilise la forme suivante : ((int)ima[i][j]). Cette forme s'appelle un «cast» : ima[i][j] et 120 sont de types différents mais numériquement compatibles : on force ima[i][j] à être considéré comme un entier au moment de sa comparaison avec 120.
Question n 3 : Écrire un programme permettant de calculer et d'afficher la somme des éléments de la diagonale principale ainsi que la somme des éléments de la diagonale secondaire d une matrice d'entiers donnée On suppose le tableau est rempli à l'avance. Correction Pour résoudre ce problème, attachons nous tout d'abord à savoir quelles sont les diagonales principales et secondaire d'une matrice. Soit la matrice suivante : Colonnes (j) Lignes (i) 0 1 2 3 0 2 4 0 9 1 3 1 5 7 2 8 5 2 6 3 9 2 3 4 Avec : les indices de ligne et de colonne la diagonale principale la première diagonale secondaire la seconde diagonale secondaire On remarque que pour chacune de ces diagonales, on peut établir une relation arithmétique entre l'indice de ligne et l'indice de colonne des éléments composant cette diagonale : On obtient ainsi: pour la diagonale principale, i=j et i va de 0 à taille_mat -1 (ici 3) pour la première diagonale secondaire, j=i+1 et i va de 0 à taille_mat -2 (ici 2) pour la seconde diagonale secondaire, j=i-1 et i va de 1 à taille_mat 1. Donc au final, notre calcul de somme sur l'une des diagonales peut être ramené à un calcul de somme sur un tableau à 1 dimension. Pour le calcul de la somme, ne pas oublier d'initialiser la variable qui contiendra la somme des valeurs. Nous aboutissons donc à la proposition de correction suivante :
int main(void) //On se propose de travailler sur une matrice d'entiers //de 10 cases par 10 cases. int mat[10][10]; //On peut ne déclarer qu'une variable contenant la somme car //le calcul des sommes n'est pas simultané. int i,somme=0; //On suppose que la matrice est remplie //Calcul et affichage de la somme des éléments de la //diagonale principale //Pour chaque élément de la diagonale principale for(i=0; i<10; i++) //Dans ce cas le numéro de ligne et de colonne sont égaux somme = somme + mat[i][i]; //Affichage printf(«la somme des éléments de la diagonale principale est : %d \n»,somme); //Calcul et affichage des éléments de la première diagonale //secondaire //<!> Attention, penser à réinitialiser somme <!> somme=0; //Pour chaque élément de la première diagonale secondaire for(i=0; i<9; i++) //Dans ce cas j=i+1 somme = somme + mat[i][i+1]; //Affichage printf(«la somme des éléments de la première diagonale secondaire est : %d \n»,somme); Dans cette proposition, nous n'effectuons et n'affichons la somme que de l'une des deux diagonales secondaire en plus de celle de la diagonale principale. C'est par choix, vu qu'en plus l'énoncé ne précise pas quelle diagonale secondaire afficher.
Question n 4 : Soit un tableau 2D de double que l'on suppose rempli. Ecrire un programme permettant de trouver le numéro de la ligne pour laquelle la somme des éléments est maximale. Correction Ici, il faut réaliser deux actions dans le même traitement : pour chaque ligne calculer la somme des éléments composant cette ligne par un jeu de comparaisons, indiquer l'indice de la ligne pour laquelle la somme des éléments est maximale. Tout d'abord, pour réaliser la somme, nous allons utiliser une boucle (nombre d'instruction connu et fini => for) qui nous permettra de parcourir chaque élément contenu sur une ligne et de les additionner. Une fois cette somme obtenue pour une ligne donnée, nous devons trouver le moyen de comparer cette somme aux sommes obtenues pour les lignes précédentes. Nous allons pour ce faire utiliser deux variables : la première, un double que nous appellerons lmax contiendra la valeur maximale parmi les sommes rencontrées la seconde, un int, que nous appellerons i_max contiendra l'indice de la ligne pour laquelle la valeur maximale a été rencontrée. Au début de notre code, nous allons arbitrairement fixer max à la somme des éléments de la première ligne afin de pouvoir réaliser la comparaison avec les autres. Donner une valeur arbitraire au départ pour le max (0 ou autre) pourrait se révéler être préjudiciable au bon fonctionnement du programme, vu que nous n'avons aucune information sur les données qui ont été saisies dans la matrice. Si l'on récapitule, l'on a : une boucle for interne sur les numéros de colonne pour calculer la somme des éléments d'une ligne une condition située après cette boucle permettant de conserver le numéro de ligne et la valeur du max si cette ligne possède une somme maximale supérieure à celles déjà rencontrées une boucle for externe pour réaliser ce traitement sur chaque ligne. une matrice de double (double mat[10][10]) que l'on suppose remplie, deux variables pour servir de compteur sur les boucles (int i,j;), une variable entière pour conserver l'indice de ligne (int i_max), deux double : l'un pour la somme des éléments d'une ligne donnée (double somme) et l'autre pour conserver la valeur maximale sur une ligne donnée (double lmax).
Nous aboutissons donc à la proposition de code suivante : int main(void) //On se propose de travailler sur une matrice de double //de 10 cases par 10 cases. double mat[10][10]; int i,j,i_max; double somme, lmax; //On suppose que la matrice est remplie //Pour chaque ligne de la matrice for(i=0;i<10;i++) somme = 0; //Calculer la somme correspondante for(j=0;j<10;j++) somme = somme + mat[i][j]; //Si cette somme est la plus élevée ou si c'est celle de //la première ligne if( (somme > lmax) (i==0)) i_max=i; lmax=somme; //Affichage final printf(«la ligne %d de la matice est la ligne pour laquelle la somme des éléments est maximale (somme= %0.2lf) \n»,i_max,lmax);
UEO12 TD2 Tri par sélection : Réaliser un programme permettant d'effectuer un tri par sélection sur un tableau 1D d'entiers, que l'on considérera rempli. Correction Au cours de cette correction nous allons tout d'abord voir l'algorithme permettant de réaliser le tri par sélection puis un exemple d'application de cet algorithme sur un tableau de 4 entiers. Tout d'abord, voyons en quoi consiste ce tri. Comme tout tri, il permet d'organiser le tableau d'entier par ordre de valeur croissant. La méthode employé consiste à «repousser» les valeurs les plus élevées vers la fin du tableau. L'algorithme peut être schématisé de la sorte : 1) Trouver l'indice de la case possédant la valeur maximale parmi les cases non triées 2) Permuter cette case avec la dernière case non triée du tableau 3) Répéter cette opération tant qu'il reste des cases à trier. Voyons un exemple d'exécution sur un tableau de 4 entiers : Indices 0 1 2 3 Valeurs 10 2 1 8