1
Annexe B
Algorithmes de la bibliothèque standard STL
Hansel, G., Passeport pour C++ Concepts et mise en pratique. Chap. 23 et annexe A,
1999.
Cay Horstmann & Timothy Budd, La Bible C++. John Wiley & Sons, Inc., 2004, 1230p.
On retrouve aussi dans la bibliothèque standard STL un jeu de fonctions appelées
algorithmes. Pour ces fonctions, l’accès aux données contenues dans un conteneur
s’effectue exclusivement par le biais d’itérateurs. Les algorithmes sont indépendants des
classes mises en jeu dans les conteneurs. De plus, un pointeur usuel pouvant être
considéré comme un cas particulier d’itérateur, les algorithmes sont également utilisables
pour les tableaux usuels.
Pour utiliser un algorithme, il faut préalablement inclure le fichier <algorithm>.
Dans l’annexe A de la référence de Hansel citée plus haut, on retrouve une description
complète des algorithmes de la STL. C’est aussi le cas des deux ouvrages suivants :
Bjarne Stroustrup, The C++ Programming Language, Special Ed., Addison-
Wesley, 2000.
Stanley B. Lippman et Josée Lajoie, C++ Primer, 3rd ed., Addison-Wesley, 1998.
La bibliothèque standard contient plusieurs douzaines d’algorithmes génériques. Nous
étudierons ici que les plus fréquents et les plus utiles. Pour simplifier la présentation de
ces fonctions, celles-ci sont réparties en plusieurs catégories.
A. Algorithmes d’initialisation
Ce sont des algorithmes servant principalement à initialiser une séquence.
Un conteneur peut être initialisé par remplissage (initialiser avec une même valeur fixe),
par copie (dupliquer des valeurs depuis un conteneur pour en remplir un second) ou par
génération (exécuter une fonction de façon répétée et employer les valeurs obtenues pour
initialiser un conteneur).
Remplissage :
Deux algorithmes permettent de remplir un conteneur. Le premier utilise comme
arguments une plage d’itérateurs et une valeur, puis affecte à chaque élément de la plage
la valeur spécifiée.
vector<int> a(10);
fill(a.begin(), a.end(), 1);
Le deuxième algorithme reçoit un itérateur, un compteur entier et une valeur. Il initialise
le nombre de positions spécifié par le compteur avec la valeur donnée.
2
fill_n(a.begin(), 5, 2); // Remplit les 5 premières positions de a avec la
// valeur 2.
Ces deux algorithmes ne peuvent servir à ajouter de nouveaux éléments dans un
conteneur mais, uniquement, à modifier la valeur de certains éléments d’un conteneur.
Copie :
L’algorithme générique copy sert à copier un conteneur dans un autre. Il reçoit 3
arguments, les deux premiers spécifiant la plage du conteneur d’entrée, le troisième
indiquant le point de départ du conteneur de destination. Il est supposé, et non vérifié, que
la destination est suffisamment grande pour accepter l’entrée.
vector<int> b(20);
copy(a.begin(), a.end(), b.begin()); // Initialise les 10 premières positions de b.
Génération :
L’algorithme générique generate permet d’initialiser un conteneur grâce à un générateur.
vector<int> c(20);
generate(c.begin(), c.end(), AleatoireInt(7, 25));
// Remplit le vecteur c de valeurs aléatoires comprises entre 7 et 25.
Lalgorithme generate_n reçoit un itérateur, un compteur entier et un générateur.
generate_n(c.begin(), 10, AleatoireInt(10, 30));
// Remplit les 10 premières composantes du vecteur c de valeurs aléatoires
// comprises entre 10 et 30.
B. Algorithmes de transformations
Cette catégorie d’algorithmes génériques permet de transformer une séquence de valeurs
en une nouvelle séquence.
l’algorithme reverse :
Cet algorithme inverse les éléments d’une séquence, de façon à ce que le dernier élément
devienne le nouveau premier, le premier le nouveau dernier, etc.
vector<int> a(10);
generate(a.begin(), a.end(), Generateur_suite(1)); // Initialement 1, 2, …, 10.
reverse(a.begin(), a.end()); // Maintenant 10, 9, 8, …, 1.
l’algorithme sort :
Pour trier des collections stockées dans un conteneur vector, un deque ou un tableau
ordinaire, nous pouvons recourir à l’algorithme générique sort.
3
vector<int> a(10);
generate(a.begin(), a.end(), AleatoireInt(10, 30));
sort(a.begin(), a.end());
L’algorithme sort ne peut être emplo avec des listes, car il cessite l’emploi
d’itérateurs d’indexation, absents des listes. Toutefois, le conteneur list contient une
fonction membre sort utilisant un autre algorithme.
l’algorithme random_shuffle :
Cet algorithme réarrange de façon aléatoire les éléments d’une collection. Il peut être
utilisé avec des vecteurs, des dèques ou des tableaux ordinaires mais non avec des listes,
des ensembles ou des cartes (map et multimap). Les arguments doivent être des itérateurs
d’accès aléatoire.
vector<int> a(10);
generate(a.begin(), a.end(), Generateur_suite(1));
random_shuffle(a.begin(), a.end());
Il est impossible de prédire ce que pourrait être la séquence résultante. Un résultat
possible serait : 9, 4, 8, 6, 2, 10, 1, 3, 5, 7.
l’algorithme rotate :
L’algorithme effectue dans une séquence une rotation autour d’un élément pivot spécifié
par un itérateur. Cela divise la séquence en deux parties non nécessairement de même
longueur, puis intervertit l’ordre des 2 parties, en conservant l’ordre relatif dans chaque
partie.
vector<int> a(10);
generate(a.begin(), a.end(), Generateur_suite(1));
vector<int>::iterator pivot = find(a.begin(), a.end(), 7);
rotate(a.begin(), pivot, a.end());
La séquence 1 2 3 4 5 6 7 8 9 10 devient 7 8 9 10 1 2 3 4 5 6.
Le pivot doit faire partie de la plage des itérateurs.
l’algorithme partition :
La séquence est formée en déplaçant tous les éléments satisfaisant à un prédicat à un bout
d’une séquence et tous les éléments échouant à ce prédicat à l’autre extrémité.
vector<int> a(10);
generate(a.begin(), a.end(), Generateur_suite(1));
partition(a.begin(), a.end(), paire);
4
Les valeurs paires sont déplacées au début et les valeurs impaires à la fin ce qui donne
comme résultat : 10 2 8 4 6 5 7 3 9 1. Comme on peut le constater, l’ordre relatif des
éléments dans une partition dans le conteneur résultant diffère de celui des valeurs dans la
séquence originale. En substituant partition par stable_partition, cela garantit le maintien
de l’ordre des valeurs résultantes : 2 4 6 8 10 1 3 5 7 9.
l’algorithme transform :
1ière version :
Étant donné une séquence d’entrée spécifiée par des itérateurs de début et de fin, une
destination de sortie spécifiée par un unique itérateur et une fonction unaire, l’algorithme
applique la fonction à chaque élément de l’entrée pour créer les éléments de sortie.
int carre(int n) { return n * n; }
vector<int> a(10);
generate(a.begin(), a.end(), Generateur_suite(1));
vector<int> b(10);
transform(a.begin(), a.end(), b.begin(), carre);
2me version :
Étant donné deux séquences d’entrée dont la première est spécifiée par des itérateurs de
début et de fin, la seconde spécifiée par un itérateur de début, une destination de sortie
spécifiée par un unique itérateur et une fonction binaire, l’algorithme applique la fonction
binaire aux éléments correspondants de l’entrée pour créer les éléments de sortie. On
suppose sans le rifier que la deuxième séquence d’entrée comporte au moins autant
d’éléments que la première et que la séquence résultat disposera de suffisamment de
place pour accueillir le résultat.
int addition(int a, int b) { return a + b; }
vector<int> c(10);
transform(a.begin(), a.end(), b.begin(), c.begin(), addition);
l’algorithme merge :
Étant donné deux séquences d’entrée triées spécifiées par des itérateurs de début et de fin,
une destination de sortie spécifiée par un unique itérateur, l’algorithme fusionne les 2
séquences triées pour obtenir une nouvelle séquence triée.
vector<int> a(10);
vector<int> b(20);
generate_n(a.begin(), 10, Generateur_suite(1));
generate_n(b.begin(), 20, Generateur_suite(5));
vector<int> c(30);
merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
5
l’algorithme next_permutation :
Une permutation est une réorganisation des valeurs dans une séquence.
Ex. : 6 permutations des valeurs 1 2 3 : 1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1.
Une séquence de n éléments possède en principe n! permutations; la première est telle
que les valeurs apparaissent en ordre croissant, tandis que dans la dernière, les valeurs
figurent en ordre décroissant.
L’algorithme next_permutation est une fonction booléenne qui transforme une séquence à
la prochaine permutation et retourne true si elle existe, false autrement.
Ex. : vector<int> a(4);
generate(a.begin(), a.end(), Generateur_suite(1));
while (next_permutation(a.begin(), a.end()))
{
cout << “Permutation de sortie “;
vector<int>::iterator p = a.begin();
while (p != a.end())
{
cout << *p << “ “;
++p;
}
cout << endl;
}
Ex. : char mot[] = "ouf" ;
char * p = mot; // Itérateur de début.
char * q = mot + strlen(mot); // Itérateur de fin.
sort(p, q); // Trie initialement les lettres en ordre croissant.
while (next_permutation(p, q)) cout << mot << endl;
C. Algorithmes de recherche
Ces algorithmes permettent de localiser des éléments dans une séquence; ils renvoient un
itérateur crivant une position. Si aucun élément n’est localisé, ils renvoient l’itérateur
de fin.
max_element et min_element :
Ex. : vector<int> d(10);
generate(d.begin(), d.end(), AleatoireInt(10, 30));
vector<int>::iterator mx = max_element(d.begin(), d.end());
vector<int>::iterator mn = min_element(d.begin(), d.end());
1 / 11 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !