Choisissez votre style : style 1,    style 2,    sans commentaire,    impression,    ancien.

Correction
Templates

Exercice 1

Exercice 1 : chemin parcouru

Exercice n°70 (pages 183 et 379) de l'ouvrage C++ par la pratique.

Voici une solution «avancée» (ici le code complet) où plusieurs concepts du cours se cumulent. Étudiez bien la solution, comparez avec ce que vous avez fait vous-même.

#include <iostream>
#include <vector>
#include <iterator>  // pour ostream_iterator -- cours de la semaine prochaine
using namespace std;

// ----------------------------------------------------------------------
template<typename type> class Matrice;

// --------------------------------------------------------------------
template<typename type>
ostream& operator<<(ostream& output, const Matrice<type>& M)
{
  for (auto const& ligne : M.contenu) {
    copy(ligne.begin(), ligne.end(),
         ostream_iterator<type>(output, " "));
    output << endl;
  }
  return output;
}

// --------------------------------------------------------------------
template<typename type>
istream& operator>>(istream& input, Matrice<type>& M)
{
  for (auto& ligne : M.contenu) {
    for (auto& element : ligne) {
      input >> element;
    }
  }

  return input;
}

// --------------------------------------------------------------------
template<typename type>
class Matrice {
  friend ostream& operator<<<type>(ostream&, const Matrice&);
  friend istream& operator>><type>(istream&, Matrice&);

public:
  // un nouveau type pour les exceptions
  enum error { WRONG_SIZES };

  Matrice(size_t n, size_t m, type val = type()) 
    : contenu(n, vector<type>(m, val)) {}

  Matrice& operator*=(const Matrice&);
  Matrice  operator*(const Matrice& right) const {
    return (Matrice(*this) *= right);
  }
  
protected:
  vector< vector<type> > contenu;
};

// ----------------------------------------------------------------------
template<typename type>
Matrice<type>& Matrice<type>::operator*=(const Matrice<type>& M2)
{
  if (contenu[0].size() != M2.contenu.size()) throw WRONG_SIZES;

  Matrice M1(*this);

  contenu.clear();
  for (size_t i(0); i < M1.contenu.size(); ++i) {
    contenu.push_back(vector<type>(M2.contenu[0].size()));

    for (size_t j(0); j < M2.contenu[0].size(); ++j) {
      contenu[i][j] = type(); // = 0
      for (size_t k(0); k < M2.contenu.size(); ++k) 
	contenu[i][j] += M1.contenu[i][k] * M2.contenu[k][j];
    }
  }

  return *this;
}

// ----------------------------------------------------------------------
Matrice<double> saisie_matrice() {
  cout << "Saisie d'une matrice :" << endl;
  cout << "  Nombre de lignes : ";
  size_t n;
  cin >> n;
  cout << "  Nombre de colonnes : ";
  size_t m;
  cin >> m;

  Matrice<double> M(n,m);
  cout << "Entrez la matrice :" << endl;
  cin >> M;

  return M;
}

// ----------------------------------------------------------------------
int main()
{
  Matrice<double> M1(saisie_matrice());
  Matrice<double> M2(saisie_matrice());
  Matrice<double> M;

  try {
    M = M1 * M2;
  }
  catch (Matrice<double>::error e) {
    switch (e) {
    case Matrice<double>::WRONG_SIZES:
      cerr << "Tailles imcompatibles pour la multiplication de matrices !"
           << endl;
      break;
    default:
      cerr << "Multiplication de matrices impossible !" << endl;
      break;
    }
  }

  return 0;
}

Dernière mise à jour : $Date: 2012-11-09 14:16:46 +0100 (ven 09 nov 2012) $  ($Revision: 191 $)