Date de première publication : 2013/11/21
Ce TP est centré sur les foncteurs et les algorithmes. Nous vous proposons de reprendre les exemples donnés en cours avec le foncteur pour générer les nombres pairs !
Pour tous les éléments cités, si vous voulez des exemples, allez sur CPPREFERENCE.COM
Classement de ZZs
En cours et au TP précédent, vous avez écrit l'operator<()
pour que les ZZs soient classés de la note la plus forte à la plus faible
class ZZ {
string nom, prenom;
double note;
// …
};
using vzz = std::vector<ZZ> ;
vzz zz;
// il faut mettre des elements
// zz.push_back(ZZ(...));
priority_queue<ZZ> tri;
for(vzz::iterator it = zz.begin();
it!=zz.end(); ++it)
tri.push(*it);
while(!tri.empty()) {
cout << tri.top() << " ";
tri.pop();
}
- Mettre en commentaire l'
operator<()
et le réécrire pour prendre en compte l'ordre lexicographique sur "nomprenom". - Écrire un foncteur qui permet de comparer les ZZs suivant leurs notes.
- Afficher les ZZs dans l'ordre lexicographique et dans l'ordre inverse des notes en utilisant deux files à priorité (une pour chaque tri).
- Quel conteneur permettrait d'afficher directement les ZZs dans l'ordre lexicographique en faisant un parcours simple (avec un itérateur ou un reverse itérateur). Coder.
Pour le dernier point, JEU , ... et MATCH
Exemples simples
Rand_0_100
- Créer un foncteur
Rand_0_100
qui génère des nombres aléatoires entre 0 et 100. - Instancier un vecteur de 50 nombres aléatoires avec
std::generate
puis avecstd::generate_n
et unback_inserter
(Bon, ça, c'est plus chaud mais c'est dans le cours). - Utiliser
std::accumulate
pour calculer la moyenne d'un échantillon (un vecteur par exemple) généré parRand_0_100
- Calculer le minimum et le maximum de l'échantillon avec
std::min_element
etstd::max_element
. - Généraliser maintenant le foncteur pour générer des nombres aléatoires entre deux bornes fournies au constructeur
- Comment transformer le foncteur pour que deux instances du foncteur ne réinitialisent pas la seed.
Nombres entiers
- Créer un foncteur qui permet d'afficher le nombre de Fibonacci d'indice n. Pour rappel, u0 = 0, u1 = 1, un=un-1 + un-2.
Afficher la liste avec
std::copy
- Créer un vecteur de nombres de 1 à 100 consécutifs. Faire le bazar avec
std::random_shuffle
. Afficher la liste à partir de l'élément 50 que vous trouverez grâce àstd::find
.
Le compilo recommandé supporte la norme C++17 où random_shuffle
est désormais obsolète. Quelle solution propose la documentation ?
Foncteurs et conteneurs
Créer un foncteur permettant de réaliser le tri sur un vecteur de std::string
(std::vector<,std::string>
) à l’aide de la fonction std::sort
en ne comparant pas l’ensemble de
la chaîne mais seulement à partir du second caractère (on supposera que le vecteur contient
uniquement des chaînes d’au moins deux caractères). Tester votre foncteur avec un jeu
d’essai simple.
Créer un dernier foncteur permettant, à l’aide de la fonction std::for_each
, de mettre en
majuscule l’ensemble des chaînes de caractères contenu dans un vecteur de string
. Tester
votre foncteur.
Illustrations de problèmes liés l'utilisation des templates et leur solution
Regardez le code ci-dessous, c'est celui qui va nous permettre d'illustrer plusieurs "astuces" à connaître pour utiliser les templates... Cela ne s'invente pas, faut le savoir et "pis c'est tout" !
template<typename T>
class Stats {
vector<T> data;
T sum;
double moy;
double ecart;
public:
Stats():data(10), moy(.0) {}
void push_back(const T& t) { data.push_back(t);}
void compute() {
}
void display(ostream& o = cout) const {
}
};
int main(int, char**) {
Stats<int> is;
is.push_back(3);
is.push_back(4);
is.push_back(2);
is.compute();
is.display();
return 0;
}
typename (!important)
Le code est incomplet ! Est-ce que vous pouvez écrire au moins une des deux méthodes vides en parcourant le conteneur avec un const_iterator
?
Pour que le code soit accepté par le compilateur, il faut utiliser typename
dans un deuxième usage :
préciser au compilateur que ce que vous déclarez existe réellement est est un type (car en l'état, le compilateur n'a aucun
moyen de le savoir)
Héritage
Écrire un code qui instancie la classe Fille sur un type simple (ou un type pour lequel il y a surcharge de l'opérateur << et *).
Vérifier également que la méthode f()
est appelable.
template<class T>
class Mere {
protected:
T a;
public:
Mere(T t):a(t) {}
void f() { std::cout << a ; }
};
template<class T>
class Fille : public Mere<T> {
public:
Fille(T t): Mere<T>(t) {}
void m() {
a = a*a;
f();
}
};
Que faut-il faire pour que cela compile ?
Cela a été vu en cours !
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10