Correction 26
Librairie standard
Exercice 1 : Ensembles et itérateurs (niveau 1)
Pour pouvoir créer un ensemble, il faut avant tout utiliser la bibliothèque correspondante. On met donc :
#include <set>
Un ensemble de caractères se déclare simplement ensuite par :
set<char> unensemble;
Pour insérer des éléments, on utilise la méthode insert :
unensemble.insert('a'); unensemble.insert('b'); unensemble.insert('c');
Si l'on souhaite maintenant parcourir cet ensemble, il nous faut un itérateur pour cette classe "ensemble". Il se déclare par set<char>::iterator.
Si on veut partir du début de l'ensemble, cela correspond pour
l'itérateur à
la valeur retournée par la méthode begin() de la
class set (comme tout container de la librairie standard).
On aura donc :
set<char>::iterator i(unensemble.begin())
De même, la valeur (suivant la) finale correspond à unensemble.end(), et pour faire avancer un itérateur on peut utiliser l'opérateur ++ comme pour les nombres et pour les pointeurs.
L'accès à la valeur du container désignée par un itérateur, par exemple i, se fait en utilisant l'opérateur * : *i
On aboutit alors à :
for (set<char>::iterator i(unensemble.begin()); i != unensemble.end(); ++i) { cout << " " << *i << endl; }
Ensuite, pour copier un container (par exemple set) dans un autre (par exemple string), il est impératif que le second ait au moins la place pour accueillir la copie, c.-à-d, ait au moins la taille du container copié.
Dans notre cas on crée donc une string avec au moins 3 caractères : string s("abc");
La copie s'effectue alors simplement avec l'algorithme générique de copie :
copy(unensemble.begin(), unensemble.end(), s.begin());
La copie sur la sortie cout se fait de même, sauf qu'il faut "transformer" le flot cout en un itérateur ; ce qui se fait avec [niveau avancé] ostream_iterator<char>(cout, ", "), où le dernier argument représente le séparateur utilisé entre chacun des éléments du container affichés.
Voici, pour finir, le code complet :
#include <iostream> // pour cout #include <algorithm> // pour copy #include <set> #include <string> #include <iterator> // pour ostream_iterator using namespace std; int main() { set<char> unensemble; unensemble.insert('a'); unensemble.insert('b'); unensemble.insert('c'); cout << "mon ensemble contient :" << endl; for (set<char>::iterator i(unensemble.begin()); i != unensemble.end(); ++i) { cout << " " << *i << endl; } string s; // pour utiliser copy, il est impératif que la chaîne ait // la place nécessaire, donc ici au moins 3 caractères. // En pratique on utilisera donc pas copy pour CREER un // nouveau container, mais bien pour COPIER des valeurs; s = "xxx"; copy(unensemble.begin(), unensemble.end(), s.begin()); cout << s << endl; // affichage cout << "mon ensemble = "; copy(unensemble.begin(), unensemble.end(), ostream_iterator<char>(cout, ", ")); cout << endl; return 0; }
Exercice 2 : tris revisités (niveau 1)
L'exercice est suffisamment simple, je crois, pour que la solution
se passe de commentaires.
Voici une solution possible (simple et "à l'ancienne", sans les nouveautés de C++11) :
#include <ctime> // pour time() #include <cstdlib> // pour rand #include <vector> #include <algorithm> #include <iostream> using namespace std; int main() { // initialisation de la séquence pseudo-aléatoire srand(time(0)); vector<double> tableau; for (unsigned int i(0); i < 25; ++i) { tableau.push_back(rand()*10.0-5.0); } cout << "avant le tri :" << endl; for (unsigned int i(0); i < tableau.size(); ++i) { cout << tableau[i] << endl; } // trie le tableau sort(tableau.begin(), tableau.end()); cout << "après le tri :" << endl; for (unsigned int i(0); i < tableau.size(); ++i) { cout << tableau[i] << endl; } return 0; }
Exercice 3 :map, itérateurs
#include <iostream> #include <vector> #include <map> using namespace std; map<int,double> remplit_map(vector<int>& v1, vector<double>& v2) { map<int,double> v1v2; vector<double>::iterator i2(v2.begin()); for (vector<int>::iterator i1(v1.begin()); i1 < v1.end(); ++i1) { v1v2[*i1] = *i2; ++i2; } return v1v2; } void afficher_map(map<int,double>& table) { for (map<int,double>::iterator i(table.begin()); i != table.end(); ++i) cout << i->first << " -> " << i->second << endl; } void supprimer(map<int,double>& table, int cle) { table.erase(cle); } void supprimer_pair(map<int,double>& table) { for (map<int,double>::iterator i(table.begin()); i != table.end(); ) { if ((i->first % 2) == 0) { //subtilité : i++ fait l'incrémentation avant l'appel // à erase alors que l'itérateur est encore valide et passe une // copie de l'itérateur non encore incrémenté à erase! table.erase(i++); } else ++i; } } int main() { vector<int> entrees; vector<double> resultats; for (int i=0;i<6;++i) { entrees.push_back(i); resultats.push_back(i*3.1); } map<int,double> mapping = remplit_map(entrees, resultats); afficher_map(mapping); supprimer(mapping,1); afficher_map(mapping); supprimer_pair(mapping); afficher_map(mapping); }