Correction du partiel d`algorithmique et programmation 1 Fusion

publicité
Département d’Informatique
DUT Informatique S1
Année 2014/2015
Algorithmique et programmation
Correction du partiel d’algorithmique et programmation
18 décembre 2014
Durée : 2 heures. Aucun document autorisé.
Indications
– le sujet comporte deux pages ;
– lire intégralement le sujet avant de commencer ;
– répondre aux questions de manière précise et concise ;
– numéroter les copies s’il y en a plusieurs ;
– laisser une marge de 2,5 cm minimum sur le bord gauche de chaque page ;
1
Fusion
Soit deux tableaux de nombres réels, les valeurs de chacun de ces tableaux sont supposées triées par ordre
croissant. Écrire un algorithme qui fusionne ces deux tableaux en un troisième tableau. Ce troisième tableau
devra contenir exactement les valeurs des tableaux d’origine, et ces valeurs devront elles aussi être triées par
ordre croissant.
Par exemple, la fusion de
1,0
1,4
2,1
5,2
7,2
8,1
9,9
1,0
1,4
2,0
2,1
2,2
2,5
et de
2,0
2,2
2,5
2,9
3,9
4,8
5,2
6,0
4,8
5,2
5,2
6,0
7,2
7,7
8,1
9,9
7,7
donnera
2,9
3,9
Correction
Données
Deux tableaux de réels triés, ainsi que leurs longueurs.
Résultat
Un tableau de réels, résultat de la fusion des deux tableaux donnés, trié.
Idée
Les deux tableaux sont parcourus en même temps, et la plus petite valeur est ajoutée au fur et à mesure au tableau
résultat, et cela jusqu’à avoir consommé toutes les valeurs d’un des tableaux source. Ensuite, les valeurs restantes
dans l’autre tableau sont recopiées inconditionnellement.
Lexique des variables
longA (entier)
tabA
(tableau [longA] de réels)
longB (entier)
tabB
(tableau [longB] de réels)
tabC
(tableau [longA + longB] de réels)
i
(entier)
j
(entier)
k
(entier)
longueur du tableau tabA
premier tableau
longueur du tableau tabB
deuxième tableau
tableau résultat
indice dans tabA
indice dans tabB
indice dans tabC
1
DONNÉE
DONNÉE
DONNÉE
DONNÉE
RÉSULTAT
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
Algorithme
i←0
j←0
k←0
tant que i < longA ∧ j < longB faire
si tabA[i] < tabB[j] alors
tabC[k] ← tabA[i]
i←i+1
sinon
tabC[k] ← tabB[j]
j ←j+1
fsi
k ←k+1
ftant
tant que i < longA faire
tabC[k] ← tabA[i]
i←i+1
k ←k+1
ftant
tant que j < longB faire
tabC[k] ← tabB[j]
j ←j+1
k ←k+1
ftant
2
Tris
1. Écrire une fonction permettant de trier un tableau d’entiers par valeurs croissantes.
Donner le nom de l’algorithme de tri utilisé.
2. Réécrire la fonction en l’adaptant pour un tableau de chaînes de caractères.
Mettez en évidence ce qui change entre les deux versions.
Pour comparer deux chaînes de caractères, on suppose qu’on dispose d’une fonction chCompare() qu’il
n’est pas demandé d’écrire :
fonction chCompare(in s1 : chaîne, in s2 : chaîne) : ret entier
Compare les deux chaînes passées en paramètre suivant l’ordre lexicographique. Retourne un nombre négatif
si s1 < s2, zéro si s1 = s2, ou un nombre positif si s1 > s2.
Correction
Cf. cours pour le premier point.
Pour le second point, il faut changer :
– le type des éléments du tableau (entier → chaîne) ;
– les type de la variable permettant de stocker une valeur (valeur, min, tmp, . . ., selon l’algorithme choisi) ;
– l’opération de comparaison entre deux valeurs, en la remplaçant par un appel à la fonction chCompare().
3
Recherche dichotomique
1. Qu’est-ce que la recherche dichotomique, dans quels cas peut-elle s’appliquer ?
Expliquez son principe.
2. Écrire, en langage algorithmique, une fonction permettant de rechercher un élément dans un tableau de
nombres réels en utilisant le principe de la recherche dichotomique.
Vous donnerez deux versions : une version récursive et une version itérative.
3. Pour chacune des deux fonctions écrites précédemment, donner une trace d’exécution pour la recherche
successive des valeurs 30, 0 et 21 dans un tableau de réels contenant les valeurs 1, 5, 9, 12, 15, 21, 29.
1
5
Le tableau.
9 12 15
2
21
29
Correction
Cf. cours pour les deux premiers points. Cf. TD pour le dernier point.
Tableau: [ 1, 5, 9, 12, 15, 21, 29 ]
Recherche de 30
===============
-> rechDichoRec(tab, 0, 6, 30): milieu = 3, tab[milieu] = 12
-> rechDichoRec(tab, 4, 6, 30): milieu = 5, tab[milieu] = 21
-> rechDichoRec(tab, 6, 6, 30): milieu = 6, tab[milieu] = 29
-> rechDichoRec(tab, 7, 6, 30): deb > fin
<- -1
<- -1
<- -1
<- -1
-> rechDichoIter(tab,
min (0) <= max (6),
min (4) <= max (6),
min (6) <= max (6),
min (7) > max (6)
<- -1
0, 6, 30):
milieu = 3, tab[milieu] = 12
milieu = 5, tab[milieu] = 21
milieu = 6, tab[milieu] = 29
Recherche de 0
===============
-> rechDichoRec(tab, 0, 6, 0): milieu = 3, tab[milieu] = 12
-> rechDichoRec(tab, 0, 2, 0): milieu = 1, tab[milieu] = 5
-> rechDichoRec(tab, 0, 0, 0): milieu = 0, tab[milieu] = 1
-> rechDichoRec(tab, 0, -1, 0): deb > fin
<- -1
<- -1
<- -1
<- -1
-> rechDichoIter(tab,
min (0) <= max (6),
min (0) <= max (2),
min (0) <= max (0),
min (0) > max (-1)
<- -1
0, 6, 0):
milieu = 3, tab[milieu] = 12
milieu = 1, tab[milieu] = 5
milieu = 0, tab[milieu] = 1
Recherche de 21
===============
-> rechDichoRec(tab, 0, 6, 21): milieu = 3, tab[milieu] = 12
-> rechDichoRec(tab, 4, 6, 21): milieu = 5, tab[milieu] = 21
<- 5
<- 5
-> rechDichoIter(tab, 0, 6, 21):
min (0) <= max (6), milieu = 3, tab[milieu] = 12
min (4) <= max (6), milieu = 5, tab[milieu] = 21
<- 5
4
Carré magique
Un carré magique est un carré de nombres tel que les sommes des nombres sur chacune de ses lignes, colonnes
et diagonales sont les mêmes.
4.1
Vérification
Écrire un algorithme permettant de vérifier si un tableau 2D de nombres est un carré magique.
Correction
3
Données
Un tableau carré de nombres entier avec sa longueur de côté.
Résultat
Un booléen indiquant si on a affaire à un carré magique.
Idée
On commence par calculer les sommes sur les diagonales. Si elles sont égales, le carré est supposé magique. Dans
ce cas, les sommes sur chacune des lignes et chacune des colonnes sont calculées et comparées à la somme sur la
diagonale. Si une des sommes ne correspond pas, le carré n’est pas magique, et l’algorithme s’arrête. Si l’algorithme
s’arrête après avoir parcouru toutes les lignes et toutes les colonnes, le carré est magique.
Lexique des
cote
carre
magique
sDiag
sADiag
sLig
sCol
i
j
variables
(entier)
(tableau [cote, cote] d’entiers)
(booléen)
(entier)
(entier)
(entier)
(entier)
(entier)
(entier)
côté du carré
tableau d’entiers à tester
le carré est-il magique ?
somme sur la diagonale
somme sur l’antidiagonale
somme sur une ligne
somme sur une colonne
indice pour le parcours
indice pour le parcours
DONNÉE
DONNÉE
RÉSULTAT
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
Algorithme
sDiag ← 0
sADiag ← 0
pour i de 0 à cote − 1 faire
sDiag ← sDiag + carre[i, i]
sADiag ← sADiag + carre[i, cote − 1 − i]
fpour
magique ← sDiag = sADiag
i←0
tant que magique ∧ i < cote faire
sLig ← 0
sCol ← 0
pour j de 0 à cote − 1 faire
sLig ← sLig + carre[i, j]
sCol ← sCol + carre[j, i]
fpour
si sLig 6= sDiag ∨ sCol 6= sDiag alors
magique ← faux
fsi
i←i+1
ftant
4.2
Génération
Voici le principe d’un algorithme permettant de générer un carré magique de côté N (N impair), en plaçant
chacun des nombres de 1 à N 2 . On peut remarquer que les sommes sont alors égales à (N (N 2 + 1))/2.
(i) placer le premier nombre (1) au milieu de la première colonne.
(ii) placer le nombre suivant dans la case en haut à gauche. Si on dépasse du tableau, placer le nombre sur la
colonne ou la ligne opposée.
(iii) recommencer l’étape (ii) N fois. On tombe alors juste avant la case d’origine.
(iv) si le carré n’est pas terminé, placer le nombre suivant sur la même ligne, une colonne à droite et continuer
à l’étape (ii).
Exemple avec N = 5, les sommes sont égales à 65 :
65
15
8
1
24
17
65
16
14
7
5
23
65
22
20
13
6
4
65
3
21
19
12
10
65
9
2
25
18
11
65
65
65
65
65
65
65
Écrire un algorithme générant, pour N un nombre impair donné, un carré magique de côté N .
4
Correction
Données
Longueur du côté du carré souhaité.
Résultat
Tableau d’entiers formant un carré magique.
Lexique des variables
cote
(entier)
carre (tableau [cote, cote] d’entiers)
lig
(entier)
col
(entier)
n
(entier)
i
(entier)
j
(entier)
Algorithme
lig ← (cote − 1)/2
col ← 0
n←1
pour i de 1 à cote faire
pour j de 1 à cote faire
lig ← (lig + cote) mod cote
col ← (col + cote) mod cote
carre[lig, col] ← n
n←n+1
lig ← lig − 1
col ← col − 1
fpour
lig ← lig + 1
col ← col + 2
fpour
côté du carré
le carré magique
numéro de ligne
numéro de colonne
valeur à entrer
compteur
compteur
DONNÉE
RÉSULTAT
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
INTERMÉDIAIRE
// rectification des indices :
// on ajoute ‘cote’ pour rester dans le domaine positif
5
Téléchargement