Choisissez votre style : colorisé, impression

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

}

Dernière mise à jour :2022/05/03 19:26:04