Algorithmique & Programmation Orientée Objet Semestre 2 ST Les tableaux de variables
Cours | TD - Corrections | TP
Le code source suivant est à utiliser dans les exercices 1 et 2. Il illustre la déclaration d'un tableau de réels, suivie du remplissage de ce tableau avec des réels tirés au sort, suivi, pour finir, de l'affichage des réels tirés au sort. Pour les exercices, on pourra ajouter les lignes de code correspondant aux questions posées à la place des points de suspension.
GenerationTableauReel.lda { Génération d'un tableau de réels } { tirés au sort entre 0.0 et 1.0 } action principale() { Taille du tableau } constante entier TAILLE <- 20 { Déclaration du tableau } reel [TAILLE] tab entier i ... { Remplissage du tableau } pour i de 0 à longueur(tab)-1 faire tab[i] <- random() fait { Affichage des valeurs du tableau } pour i de 0 à longueur(tab)-1 faire afficherln(tab[i]) fait ... fin action Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°1: Tableaux "simples" a) On considère l'existence d'un tableau de réels. Ecrire un algorithme permettant de parcourir ce tableau pour afficher les valeurs qu'il contient qui sont comprises entre une borne réelle minimale et une borne réelle maximale (bornes incluses).
AffichageTableauSeuils.lda { Affichage d'un tableau de reels } { pour les valeurs comprises } { entre des bornes minimale et maximale } action principale() { Taille du tableau } constante entier TAILLE <- 20 { Déclaration du tableau } reel [TAILLE] tab entier i réel min réel max { Acquisition clavier de min et de max } afficher("SVP, valeur minimale? ") min <- saisir() afficher("SVP, valeur maximale? ") max <- saisir() { Remplissage du tableau } pour i de 0 à longueur(tab)-1 faire tab[i] <- random() fait { Affichage des valeurs du tableau } pour i de 0 à longueur(tab)-1 faire afficherln(tab[i]) fait sautDeLigne() { Affichage des valeurs du tableau } { comprises dans l'intervalle [min,max] } pour i de 0 à longueur(tab)-1 faire si ( ( tab[i] >= min ) et ( tab[i] <= max ) ) alors afficherln(tab[i]) fsi fait fin action Clavier.class - Ecran.class - Exemple d'exécution
b) On considère l'existence d'un tableau de réels. Ecrire un algorithme permettant de calculer et d'afficher la moyenne des valeurs contenues dans ce tableau.
MoyenneTableau.lda { Calcul de la moyenne des valeurs contenues } { dans un tableau de reels } action principale() { Taille du tableau } constante entier TAILLE <- 20 { Déclaration du tableau } reel [TAILLE] tab entier i reel moyenne { Remplissage du tableau } pour i de 0 à longueur(tab)-1 faire tab[i] <- random() fait { Affichage des valeurs du tableau } pour i de 0 à longueur(tab)-1 faire afficherln(tab[i]) fait sautDeLigne() { Calcul puis affichage de la moyenne } { des valeurs du tableau } moyenne <- 0.0 pour i de 0 à longueur(tab)-1 faire moyenne <- moyenne+tab[i] fait moyenne <- moyenne/longueur(tab) afficherln("La moyenne est ",moyenne) fin action Clavier.class - Ecran.class - Exemple d'exécution
c) On considère l'existence d'un tableau de réels. Ecrire un algorithme permettant de déterminer et d'afficher le nombre de valeurs présentes dans ce tableau qui sont inférieures ou égales à une valeur réelle limite.
NombreValeursInferieuresLimite.lda { Calcul du nombre de valeurs inférieures } { ou egales a une valeur limite trouvees } { dans un tableau de reels } action principale() { Taille du tableau } constante entier TAILLE <- 20 { Déclaration du tableau } reel [TAILLE] tab reel limite entier cpt afficher("SVP, valeur limite? ") limite <- saisir() { Remplissage du tableau } pour i de 0 à longueur(tab)-1 faire tab[i] <- random() fait { Affichage des valeurs du tableau } pour i de 0 à longueur(tab)-1 faire afficherln(tab[i]) fait sautDeLigne() { Calcul puis affichage du nombre } { des valeur du tableau inferieures } { ou egales a la valeur limite saisie } cpt <- 0 pour i de 0 à longueur(tab)-1 faire si tab[i] <= limite alors cpt <- cpt+1 fsi fait afficherln("Nombre valeurs < a ",limite,": ",cpt) fin action Clavier.class - Ecran.class - Exemple d'exécution
d) On considère l'existence d'un tableau de réels. Les valeurs qu'il contient sont comprises dans l'intervalle [0.0, 20.0[. Ecrire un algorithme permettant de calculer et d'afficher les nombres de valeurs de ce tableau comprises dans les intervalles [0.0,1.0[, [1.0, 2.0[, [2.0, 3.0[, ..., [19.0, 20.0[ (opération de "classification" en statistiques).
ClassificationTableau.lda { Calcul des nombres de de valeurs } { par intervalle de largeur 1.0 } { pour un tableau de reels compris } { dans l'intervalle [0.0,20.0[ } action principale() { Taille du tableau } constante entier TAILLE <- 20 { Déclaration du tableau } reel [TAILLE] tab entier i entier [20] classification entier cl { Remplissage du tableau } pour i de 0 à longueur(tab)-1 faire tab[i] <- random()*20.0 fait { Affichage des valeurs du tableau } pour i de 0 à longueur(tab)-1 faire afficherln(tab[i]) fait sautDeLigne() { Calcul puis affichage des nombres } { de valeurs par intervalle de largeur } { 1.0 pour le tableau de double compris } { dans l'intervalle [0.0,20.0[ } pour i de 0 à longueur(classification)-1 faire classification[i] <- 0 fait pour i de 0 à longueur(t)-1 faire cl <- (entier) t[i] classification[cl] <- classification[cl]+1 fait afficherln("Nombres valeurs:") pour i de 0 à longueur(classification)-1 faire afficherln(i," ",classification[i]) fait fin action Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°2: Tableaux en sous-algorithmes a) Ecrire un sous-algorithme de génération d'un tableau de n réels (n donné) au moyen de valeurs tirées au sort dans l'intervalle [0.0,max[ où max est un réel donné. Ecrire un sous-algorithme d'affichage des valeurs contenues dans un tableau de réels.
FonctionsGenerationTableau.lda { Fonction d'affichage d'un tableau de reels } { tab : Le tableau à afficher } action affichage(-> reel [] tab) entier i pour i de 0 à longueur(tab)-1 faire afficherln(tab[i]) fait fin action { Fonction d'initialisation d'un tableau } { de réels avec des nombres tirés au sort } { dans l'intervalle [0.0,max[ réel } { max : La borne supérieure de l'intervalle } { tab : Le tableau à initialiser } action initialisationRand(-> reel [] tab ->, -> reel max) entier i pour i de 0 à longueur(tab)-1 faire tab[i] <- random()*max fait fin action { Fonction de génération et retour } { d'un tableau de réels avec des nombres } { tirés au sort dans l'intervalle [0.0,max[ } { réel } { n : La taille du tableau à générer } { max : La borne supérieure de l'intervalle } reel [] fonction generationRand(-> entier n, -> reel max) reel [n] tab initialisationRand(tab,max) retourner tab fin fonction Clavier.class - Ecran.class - Exemple d'exécution
b) Reprendre les questions (c) et (d) de l'exercice n°1 en les implantant avec utilisation de sous-algorithmes.
FonctionNombreValeursInferieuresLimite.lda { Fonction de calcul et retour du nombre } { de valeurs inférieures ou égales } { à une valeur limite réelle } { trouvées dans un tableau de reel } { t : Le tableau où est effectuée la recherche } { limite : La valeur limite de recherche } entier fonction nbValeursInferieuresLimite(-> reel [] t, -> reel limite) entier cpt entier i cpt <- 0 pour i de 0 à longueur(t)-1 faire si t[i] <= limite alors cpt <- cpt+1 fsi fait retourner cpt fin fonction Clavier.class - Ecran.class - Exemple d'exécution
FonctionClassificationTableau.lda { fonction de calcul des nombres de valeurs } { par intervalle de largeur 1.0 } { pour un tableau de reels compris } { dans l'intervalle [0.0,20.0[ } { et retour de ces valeurs dans un tableau } { t : Le tableau de réel de recherche } entier [] fonction classification(-> reel [] t) entier i entier cl entier [20] classification pour i de 0 à longueur(classification)-1 faire classification[i] <- 0 fait pour i de 0 à longueur(t)-1 faire cl <- (entier) t[i] classification[cl] <- classification[cl]+1 fait retourner classification fin fonction Clavier.class - Ecran.class - Exemple d'exécution
c) Ecrire un sous-algorithme de fusion de deux tableaux d'entiers triés en un seul nouveau tableau d'entiers trié.
FusionTableaux.lda { Fonction de fusion de 2 tableau d'entiers } { triés en un nouveau tableau d'entiers trié } { et retour du tableau ainsi obtenu } { t1 : Le premier tableau d'entier } { t2 : Le second tableau d'entier } entier [] fonction fusion(-> entier [] t1, -> entier [] t2) entier n1 <- longueur(t1) entier n2 <- longueur(t2) entier [n1+n2] t entier i entier i1 entier i2 i1 <- 0 i2 <- 0 pour i de 0 à n1+n2-1 faire si i1 == n1 alors t[i] <- t2[i2] i2 <- i2+1 sinon si i2 == n2 alors t[i] <- t1[i1] i1 <- i1+1 sinon si t1[i1] < t2[i2] alors t[i] <- t1[i1] i1 <- i1+1 sinon t[i] <- t2[i2] i2 <- i2+1 fsi fsi fsi fait retourner t fin fonction Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°3: Tableaux de variables de type agrégé a) On considère le type agrégé sommet3D constitué des 3 champs x, y et z réels représentant une position dans un espace 3D. On considère un tableau de N sommet3D (N est une constante). Développer un sous-algorithme de calcul du barycentre d'un nuage de points stocké dans un tel tableau. On rappelle que le barycentre d'un nuage de points est le point dont: - la coordonnée x est la moyennes des coordonnées x des points du nuage, - la coordonnée y est la moyennes des coordonnées y des points du nuage, - la coordonnée z est la moyennes des coordonnées z des points du nuage.
BarycentreNuageSommets3D.lda { Type agrege de stockage d'un sommet 3D } structure sommet3D reel x <- 0.0 reel y <- 0.0 reel z <- 0.0 fin structure { Fonction de calcul et retour du barycentre } { d'un nuage de points stocké dans un tableau } { de sommet3D } { tp : Le tableau de sommet3D } sommet3D fonction barycentre(sommet3D [] tp) sommet3D p entier i pour i de 0 à longueur(tp)-1 faire p.x <- p.x+tp[i].x p.y <- p.y+tp[i].y p.z <- p.z+tp[i].z fait p.x <- p.x/longueur(tp) p.y <- p.y/longueur(tp) p.z <- p.z/longueur(tp) retourner p fin fonction Clavier.class - Ecran.class - Exemple d'exécution
b) On considère le type agrégé sommet2D constitué des 2 champs x et y réels représentant l'abscisse et l'ordonnée d'une position du plan. 1) Développer un sous-algorithme de création d'un tableau de sommet2D initialisé avec les positions des sommets d'un polygone régulier respectant les propriétés suivantes: - Son rayon est r. - Il possède n sommets. - Il est centré sur l'origine. - L'un de ses sommets est en position (r,O.O). 2) Développer un sous-algorithme de calcul de la longueur d'une ligne polygonale non fermée stockée dans un tableau de sommet2D. 3) Développer un sous-algorithme de calcul de la longueur d'une boucle polygonale (fermée) stockée dans un tableau de sommet2D. Les positions des n sommets d'un polygone régulier respectant les propriétés demandées peuvent être obtenues en calculant les n couples de valeurs (r*cos(alpha),r*sin(alpha)) avec alpha = i*2.0*PI/n et i variant de 0 à n-1. On rappelle que la distance d existant entre deux positions du plan (x1,y1) et (x2,y2) peut être calculée en utilisant la formule d = sqrt((x2-x1)2+(y2-y1)2)
TableauSommets2D.lda constante reel PI <- 3.14159 { Type agrege de stockage d'un sommet 2D } structure sommet2D reel x <- 0.0 reel y <- 0.0 fin structure { Fonction de création et retour d'un tableau } { de sommet2D avec les positions } { des sommets d'un polygone regulier } { centré sur l'origine et de rayon r } { n : Le nombre de sommets du polygone } { r : Le rayon du polygone régulier } sommet2D [] fonction polygoneRegulier(-> entier n, -> reel r) i entier reel angle sommet2D [n] t pour i de 0 à longueur(t)-1 faire angle <- i*2.0*PI/longueur(t) t[i].x <- r*cos(angle) t[i].y <- r*sin(angle) fait retourner t fin fonction { Fonction de calcul et retour de la distance } { existant entre deux sommet2D } { p1 : Le premier sommet2D } { p2 : Le second sommet2D } reel fonction distance(-> sommet2D p1, -> sommet2D p2) réel l réel dx réel dy dx <- p2.x-p1.x dy <- p2.y-p1.y l <- sqrt(dx*dx+dy*dy) retourner l fin fonction { Fonction de calcul et retour de la longueur } { d'une ligne polygonale ouverte stockée } { dans un tableau de sommet2D } { t : Le tableau de sommet2D définissant } { la ligne polygonale } reel fonction longueurLigne(-> sommet2D [] t) reel l entier i l <- 0.0 pour i de 0 à longueur(t)-2 faire l <- l+distance(t[i],t[i+1]) fait retourner l fin fonction { Fonction de calcul et retour de la longueur } { d'une boucle polygonale stockée } { dans un tableau de sommet2D } { t : Le tableau de sommet2D définissant } { la boucle polygonale } reel fonction longueurBoucle(-> sommet2D [] t) réel l l <- longueurLigne(t) + distance(t[0],t[longueur(t)-1]) retourner l fin fonction Clavier.class - Ecran.class - Exemple d'exécution
Exercice n°4: Type agrégé avec tableau a) Vous êtes employé au service "contrôle qualité" d'une usine de fabrication de fraises Tagada. Vous devez concevoir un programme informatique permettant d'analyser des échantillons de fraises pour vérifier divers critères. Parmi ceux-ci nous allons nous attacher au poids. 1) Développer un type agrégé permettant de coder un échantillon en conservant les informations suivantes: le numéro de la machine de fabrication, la date de fabrication, 1000 poids de fraise (fraises sélectionnées aléatoirement sur la machine). On précise que numéro de machine est un entier, la date de fabrication est une chaine de caractères (format "jj/mm/aaaa") et le poids d'une fraise est un réel comptant en grammes. 2) Développer un sous-algorithme de calcul du pourcentage de fraises d'un échantillon qui ne respectent pas le critère consistant à avoir un poids compris entre une valeur minimale et une valeur maximale. 3) Développer un sous-algorithme de détermination de la valeur médiane des 1000 poids au sens de l'ordre croissant des poids. On rappelle que la valeur médiane d'un ensemble de valeurs selon un critère d'ordre total est une valeur v telle qu'il existe dans l'ensemble "autant" de valeurs respectant le critère vis à vis de v que de valeurs ne le respectant pas. Pour un ensemble dont le nombre d'éléments n est impair, on pourra prendre comme médiane la valeur du (n/2+1)eme élément de l'ensemble après tri selon le critère. Si le nombre d'éléments est pair, on pourra prendre comme médiane la valeur moyenne des (n/2)eme et (n/2+1)eme éléments de l'ensemble après tri selon le critère. On pourra spécifier et considérer comme existant un sous-algorithme permettant de trier un ensemble de valeurs réelles stocké dans un tableau.
EchantillonFraisesTagada.lda { Type agrege de stockage d'un echantillon } { de poids pour 1000 fraises Tagada } structure echantillonFraises entier numeroMachine <- 0 chaine dateEchantillon <- "01/01/1901" reel [1000] poids fin structure { Fonction de calcul et retour du pourcentage } { de fraises présentes dans un echantillon } { qui ont un poids hors d'un intervalle } { à bornes réelles [minimum,maximum] } { ef : L'echantillonFraises analysé } { minimum : La borne inférieure réelle } { de l'intervalle de recherche } { maximum : La borne supérieure réelle } { de l'intervalle de recherche } réel fonction pourcentagePoidsHorsLimites(-> echantillonFraises ef, -> reel minimum, -> reel maximum) réel prctg entier i entier cpt cpt <- 0 pour i de 0 à longueur(ef.poids)-1 faire si ( ( ef.poids[i] < minimum ) ou ( ef.poids[i] > maximum ) ) alors cpt <- cpt+1 fsi fait prctg <- cpt/10.0 retourner prctg fin fonction { Fonction de calcul et retour de la valeur } { médiane du poids des fraises présentes } { dans un echantillon } { ef : L'echantillonFraises analysé } réel fonction medianePoids(-> echantillonFraises ef) réel mediane réel [] poidsTries entier indice poidsTries <- ensembleTrie(ef.poids) indice <- longueur(ef.poids)/2-1 mediane <- (ef.poids[indice]+ef.poids[indice+1])/2.0 retourner mediane fin fonction { Fonction de génération et retour } { du tableau de réels contenant les mêmes } { valeurs qu'un tableau de réels "source", } { mais ordonnées par ordre croissant } { src : Le tableau de réels source } reel [] fonction ensembleTrie(-> reel [] src) ... fin fonction Clavier.class - Ecran.class - Exemple d'exécution
b) On souhaite calculer le coefficient de corrélation linéaire défini entre deux séries de N=15 données réelles. 1) Définir un type agrégé permettant de stocker ces deux séries de données en une seule variable. 2) Implanter un sous-algorithme permettant de calculer le coefficient de corrélation linéaire existant entre les deux séries de données stockées au sein d'une variable du type agrégé de la question (1). On utilisera la formule de calcul suivante définie pour les séries x et y numérotée de 1 à N (wikipedia): Les x et y surmontés d'une barre horizontale désignent en mathématique les moyennes des séries x et y.
CoefficientCorrelationLineaire.lda constante entier N <- 15 { Type agrege de stockage de deux tableaux } { de 15 reel } structure deuxSeries reel [N] x reel [N] y fin structure { Fonction de calcul et retour de la moyenne } { des valeurs contenues dans un tableau } { de reel } { t : Le tableau de calcul } réel fonction moyenne(-> réel [] t) reel moyenne entier i moyenne <- 0.0 pour i de 0 à longueur(t)-1 faire moyenne <- moyenne+t[i] fait moyenne <- moyenne/longueur(t) retourner moyenne fin fonction { Fonction de calcul et retour de l'ecart } { quadratique des valeurs contenues } { dans un tableau de reel } { t : Le tableau de calcul } { m : La valeur par rapport à laquelle } { le calcul est réalisé } réel fonction ecartQuadratique(-> réel [] t,-> réel m) réel v entier i v <- 0.0 pour i de 0 à longueur(t)-1 faire v <- v + (t[i]-m)*(t[i]-m) fait v <- sqrt(v) retourner v fin fonction { Fonction de calcul et retour du coefficient } { de correlation lineaire existant } { entre deux series de valeurs reelles } { ds : Le paramètre de type deuxSeries } { dans lequel sont stockées } { les deux séries } réel fonction coefficientCorrelation(-> deuxSeries ds) réel cc entier i réel mx réel my réel eqmx réel eqmy mx <- moyenne(ds.x) my <- moyenne(ds.y) cc <- 0.0 pour i de 0 à N-1 faire cc <- cc + (ds.x[i]-mx)*(ds.y[i]-my) fait eqmx <- ecartQuadratique(ds.x,mx) eqmy <- ecartQuadratique(ds.y,my) cc <- cc/(eqmx*eqmy) retourner cc fin fonction Clavier.class - Ecran.class - Exemple d'exécution
c) On souhaite implanter une "structure de données" permettant de stocker un ensemble de chaînes de caractères pour un maximum de 20 chaînes de caractères. 1) Définir un type agrégé permettant de stocker un tel ensemble (initialisé à l'ensemble vide). 2) Implanter un sous-algorithme permettant d'afficher les chaînes de caractères présentes dans un ensemble de chaînes de caractères. 3) Implanter un sous-algorithme permettant d'ajouter une chaîne de caractères à un ensemble de chaînes de caractères (l'ajout d'une chaîne existant déjà est autorisé). 4) Implanter un sous-algorithme permettant de tester si une chaîne de caractères appartient à un ensemble de chaînes de caractères. 5) Implanter un sous-algorithme permettant de fusionner 2 ensembles de chaînes de caractères en un nouvel ensemble de chaînes de caractères. 6) Implanter un sous-algorithme permettant de retirer une chaîne de caractères d'un ensemble de chaînes de caractères. 7) Implanter un sous-algorithme permettant de tester si un ensemble de chaînes de caractères est vide.
EnsembleDeChainesDeCaracteres.lda constante entier N <- 20 { Type agrege de stockage d'un ensemble } { d'au maximum 20 chaines de caracteres } structure ensembleDeChaines entier n <- 0 chaine [N] s fin structure { Action d'affichage des chaines } { de caracteres contenues dans un ensemble } { de chaines de caracteres } { edc : L'ensembleDeChaines à afficher } action affichage(-> ensembleDeChaines edc) entier i pour i de 0 à edc.n faire afficherln(edc.s[i]) fait fin action { Fonction d'ajout d'une chaine de caracteres } { à un ensemble de chaines de caracteres } { Retourne vrai si l'ajout a abouti } { Retourne faux si plus de place } { edc : L'ensembleDeChaines où l'ajout } { est effectué } { s : La chaine ajoutée } booleen fonction ajout(-> ensembleDeChaines edc ->, -> chaine s) res booleen si edc.n < N alors edc.s[edc.n] <- s edc.n <- edc.n+1 res <- vrai sinon res <- faux fsi retourner res fin fonction { Fonction de test de l'appartenance } { d'une chaine de caracteres } { a un ensemble de chaines de caracteres } { Retour de vrai si present, faux sinon } { edc : L'ensembleDeChaines où la recherche } { est effectuée } { s : La chaine recherchée } booleen fonction appartient(-> ensembleDeChaines edc, -> chaine s) booleen res res <- faux i <- 0 tantque ( res == faux ) et ( i < edc.n ) faire res <- (edc.s[i] == s) i <- i+1 fait retourner res fin fonction { Fonction de fusion de deux ensembles } { de chaines de caracteres dans un ensemble } { de chaines de caracteres } { Retour de faux si fusion impossible } { car pas assez de place et ne touche pas } { au parametre en sortie } { Retour de vrai sinon } { edc1 : Le premier ensembleDeChaines } { edc2 : Le second ensembleDeChaines } { edc : L'ensembleDeChaines issu de la fusion } booleen fonction fusion(-> ensembleDeChaines edc1, -> ensembleDeChaines edc2, ensembleDeChaines edc ->) entier i booleen res si edc1.n+e2.n <= N alors edc.n <- 0 pour i de 0 à edc1.n-1 faire ajout(edc,edc1.s[i]) fait pour i de 0 à edc2.n-1 faire ajout(edc,edc2.s[i]) fait res <- vrai sinon res <- faux fsi retourner res fin fonction { Fonction de retrait d'une chaine } { de caracteres a un ensemble de chaines } { de caracteres } { Retour de vrai si le retrait a abouti } { Retour de faux sinon } { edc : L'ensembleDeChaines où le retrait } { est réalisé } { s : La chaine retirée } booleen fonction retrait(-> ensembleDeChaines edc ->, -> chaine s) booleen res entier i res <- faux i <- 0 tantque ( res == faux ) et ( i < edc.n ) faire res <- (edc.s[i] == s) i <- i+1 fait si res alors pour i de i à edc.n-1 faire edc.s[i-1] <- edc.s[i] fait edc.n <- edc.n-1 fsi retourner res fin fonction { Fonction de test si un ensemble de chaines } { de caracteres est vide } { Retour de vrai si c'est le cas, faux sinon } { edc : L'ensembleDeChaines testé } booleen fonction estVide(-> ensembleDeChaines edc) retourner (edc.n == 0) fin fonction Clavier.class - Ecran.class - Exemple d'exécution