This is an old revision of the document!
La classe de la bibliothèque C++ standard dite STL (Standard Template Library) std::vector est définie comme suit :
template <class T, class Alloc=allocator<T>> class vector;
vous trouverez en plus des éléments décrivant la classe dans l’annexe du TD plus d’informations à ce lien.
Pour l’instant, nous ignorons le paramètre Alloc
.
Pour pouvoir utiliser cette classe, il est impératif de charger le fichier qui contient la définition de la classe :
#include<vector>
Nous nous intéressons pour trier des éléments dans un tableau dynamique de type std::vector<int>. L’ensemble des fonctions sera créé dans un nom d’espace appelé monomorphic.
Le fichier d’entête simple_sort.hpp
expose trois fonctions :
populate_with_randoms
initialise le vecteur theVector
avec theNumberOfValues
valeurs entières
tirées au hasard entre theMinValue
et theMaxValue
,
print_vector
affiche l'ensemble des valeurs entières contenues dans un vecteur d'entiers,simple_sort
tire les valeurs d'un vecteur d'entiers de la plus petite à la plus grande.
Le fichier simple_sort.hpp
ressemblera au fichier suivant :
#ifndef simple_sortHPP #define simple_sortHPP #include<vector> namespace monomorphic { void populate_with_randoms( std::vector<int>& theVector, int theNumberOfValues, int theMinValue, int theMaxValue); void print_vector(const std::vector<int>& anArray); void simple_sort(std::vector<int>& theValues); } #endif
Le fichier de code simple_sort.cpp
ressemblera au fichier suivant :
#include"simple_sort.hpp" #include<iostream> #include<stdlib.h> namespace monomorphic { void populate_with_randoms(std::vector<int>& theVector, int theNumberOfValues, int theMinValue, int theMaxValue) {…} void print_vector(const std::vector<int>& anArray) {…} void simple_sort(std::vector<int>& theValues) {…} }
Écrivez une fonction qui prend un objet de type std::vector<int>
et
qui ajoute à cet objet un certains nombres de valeurs aléatoires theNumberOfValues
comprises entre theMinValue
et theMaxValue
.
void populate_with_randoms(std::vector<int>& theVector, int theNumberOfValues, int theMinValue, int theMaxValue) {…}
Ecrivez the une fonction qui affiche un objet de type std::vector<int> vers la console qui aura l’entête suivante :
void print_vector(const std::vector<int>& anArray) {…}
Ajoutez la fonction de tri sur le tableau.
void simple_sort(std::vector<int>& theValues) { for (int i = 0; i<theValues.size(); i++) { for (int j = i + 1; j< theValues.size(); j++) { // Compare si les deux elements sont dans le bon ordre. if (theValues[i] > theValues[j]) { // Procede a la permutation des deux elements int Temp = theValues[i]; theValues[i] = theValues[j]; theValues[j] = Temp; } } } }
Tester le code que vous avez créé sur un exemple simple, par exemple en créant un tableau de 10 valeurs aléatoires en 1 et 10, l’affichant ensuite, le triant et l’affichant de nouveau.
Nous souhaitons étendre cet algorithme de tri fonctionnant sur des entiers à des objets qui peuvent manipuler d’autres éléments que des entiers.
L’ensemble des fonctions sera créé dans un nom d’espace appelé generic.
Le fichier d’entête generic_sort.hpp
ressemblera au fichier suivant :
#ifndef generic_sortHPP #define generic_sortHPP #include<vector> namespace generic { // Version générique des fonctions populate_with_randoms print_vector; simple_sort } #endif
Il n’y aura pas de fichier generic_sort.cpp
. Expliquer pourquoi ?
Proposer une réécriture des fonctions populate_with_randoms
, print_vector
et simple_sort
pour qu’elles puissent fonctionner avec n’importe quel autre type comme des double
, des float
, des short
, des unsigned
.
Tester vos fonctions génériques pour différents types. <hidden Correction>
Vous créez une fonction main
pour appeller les fonctions précédentes pour différents types. Dans l'exemple suivant qui est proposé, nous testons les fonctions génériques pour les types int
, float
, char
. Vous pouvez tester avec d'autres types supportant la conversion d'une valeur numérique vers le type T
.
#include"simple_sort.hpp" #include<iostream> #include<vector> int main() { { using namespace generic; std::vector<int> values; populate_with_randoms(values, 10, 20, 40); print_vector(values); simple_sort(values); print_vector(values); std::vector<float> floatValues; populate_with_randoms(floatValues, 10, 20.0, 40.0); print_vector(floatValues); simple_sort(floatValues); print_vector(floatValues); std::vector<char> charValues; populate_with_randoms(charValues, 10, 'A', 'Z'); print_vector<char>(charValues); simple_sort(charValues); print_vector(charValues); } return 0; }
Pour les types int
et float
, le comportement est équivalent à celui des fonctions monomorphiques puisque notre implantation du générateur de nombres aléatoires génères des entiers entre les valeurs minimales et maximales. Lors de l'affichage des valeurs dans le vecteur, que le type soit int
ou float
, les valeurs sont des valeurs entières. Cependant dans le dernier cas, nous manipulons des caractères et plus exactement le code ASCII des caractères. Nous générons les codes aléatoirements entre 'A' et 'Z', quand la fonction print_vector
affiche les valeurs, elle affiche le caractère correspondant au code ASCII situé entre la valeur représentant 'A' et la valeur représentant 'Z'. En conséquence de quoi, elle affiche un caractère supérieur ou égal à 'A' et inférieur ou égal à 'Z'.