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);
}