c'est une classe template (Array2D) qui permet de gerer un tableau 2d dynamique redimensionnable
on peut par exemple : créé un tableau à partir d'un buffer, d'un vector ou d'un valarray
rajouter / supprimer autant de lignes ou de colonnes que l'on souhaite
acceder a un elements avec l'operateur () (ex : matrice(1,2)=5 )
faire divers opération valeur par valeur comme l'addition, la soustraction, ... tout en restant compatible avec les tableaux classiques grace à la methode c_array() (équivalent de c_str() pour une string)
cette classe supporte aussi quelque opération sur les matrices ( produit matriciel, transposée, matrice identité)
on peut se servir du tableau 2d comme un tableau a une dimension avec l'operateur [], des methodes de tri, de min et max, d'inversion
c'est un debut mais j'attend tout suggestion pour améliorer cette classe et la rendre le plus fonctionnelle possible, ou alors si vous trouvez un bug ou autres
entirement securisé (canonique, accesseurs avec controle de bord) et 100% compatible c++ standard, 0 warning avec :
g++ -std=c++98 -Wall -W
Source / Exemple :
// interface de la classe Array2D
template <class Type> class Array2D
{
Type *values; // données
std::size_t _size; // nombre de valeurs
std::size_t _nbRow; // nombre de lignes
std::size_t _nbCol; // nombre de colonnes
public:
// constructeur par defaut
Array2D();
// destructeur
~Array2D();
// constructeur par copie
Array2D(const Array2D &v);
// constructeurs
Array2D(const std::vector< std::vector< Type > > &v);
Array2D(const std::valarray< std::valarray< Type > > &v);
Array2D(const std::vector< Type > &v, int nbCol);
Array2D(const std::valarray< Type > &v, int nbCol);
Array2D(const Type *v, std::size_t nbRow, std::size_t nbCol);
Array2D(std::size_t nbRow, std::size_t nbCol);
Array2D(std::size_t nbRow, std::size_t nbCol, const Type &init_value);
// operateurs d'affection
Array2D& operator = (const Array2D &v);
Array2D& operator = (const std::vector< std::vector< Type > > &v);
Array2D& operator = (const std::valarray< std::valarray< Type > > &v);
// accesseurs
//
// remarque : l'opérateur () (opérateur fonctionnel) permet d'accéder
// à un élément du tableau 2D en spécifiant l'indice de sa ligne et
// de sa colonne.
std::size_t size() const;
std::size_t row() const;
std::size_t col() const;
Type operator [] (std::size_t ind) const;
Type operator () (std::size_t indR, std::size_t indC) const;
Type eltAt (std::size_t ind) const;
Type eltAt (std::size_t indR, std::size_t indC) const;
Type& operator [] (std::size_t ind);
Type& operator () (std::size_t indR, std::size_t indC);
Type& eltAt(std::size_t ind);
Type& eltAt(std::size_t indR, std::size_t indC);
// retourne c-style array
const Type* c_array() const;
// redimensionne
void resize(std::size_t nbRow, std::size_t nbCol);
void resize(std::size_t nbRow, std::size_t nbCol, const Type &init_value);
// operateurs de comparaison
bool operator == (const Array2D &v) const;
bool operator != (const Array2D &v) const;
bool operator < (const Array2D &v) const;
bool operator > (const Array2D &v) const;
bool operator <= (const Array2D &v) const;
bool operator >= (const Array2D &v) const;
// operateurs de calcul :
// + ==> addition valeur par valeur
// - ==> soustraction valeur par valeur
// * ==> multiplication valeur par valeur
// / ==> division valeur par valeur
// ^ ==> produit matriciel
Array2D& operator += (const Array2D &v);
Array2D& operator -= (const Array2D &v);
Array2D& operator *= (const Array2D &v);
Array2D& operator /= (const Array2D &v);
Array2D& operator ^= (const Array2D &v);
Array2D operator + (const Array2D &v) const;
Array2D operator - (const Array2D &v) const;
Array2D operator * (const Array2D &v) const;
Array2D operator / (const Array2D &v) const;
Array2D operator ^ (const Array2D &v) const;
// operateurs d'incrémentation / décrémentation postfixés et préfixés
Array2D operator ++ (int);
Array2D& operator ++ ();
Array2D operator -- (int);
Array2D& operator -- ();
// méthode permettant de charger la matrice identité
// La matrice doit etre carré.
void setIdentity();
// retrourne la transposée de la matrice
Array2D transpose();
// valeurs min et max
static std::size_t v_min(const Type *v, std::size_t beg, std::size_t end);
static std::size_t v_max(const Type *v, std::size_t beg, std::size_t end);
Type min() const;
Type max() const;
// tri croissant et décroissant
void sort();
void usort();
// inverse l'ordre
void reverse();
};
// un main de test
// fonction qui affiche le contenu d'un Array2D<int>
void display(const Array2D<int> &v);
// une fonction prenant en parametre un pointeur sur int et
// la taille du buffer, retourne la valeur max
int MaxValue(const int *v, size_t size);
int main()
{
const int tab[][3]={ {1,2,3}, {3,2,1}, {2,1,3} };
// constrution d'un Array2D à partir d'un tableau
Array2D<int> v1( (int *)tab,3,3);
std::cout << "v1 :\n";
display(v1);
// construction d'un valarray à partir d'un tableau
std::valarray<int> va( (int *)tab, 9);
// construction d'un Array2D à partir d'un valarray
Array2D<int> v2(va,3);
std::cout << "v2 :\n";
display(v2);
// redimensionnement de v2 de 3x3 à 4x4
// les valeurs non renseignée sont initialisée à 0
v2.resize(4,4,0);
std::cout << "v2 apres resize\n";
display(v2);
// affectation
v2=v1;
std::cout << "apres v2=v1, v2 :\n";
display(v2);
if( v1 == v2) std::cout << "v1 et v2 sont identiques\n\n";
// modification de la valeur se trouvant à la 3e colonne
// de la 2e ligne
v1(1,2)=8;
if( v1 != v2) std::cout << "apres v1(1,2)=8; v1 et v2 sont different\n";
display(v1);
// constructeur par copie et opérateur d'addition
Array2D<int> v3=v1+v2;
display(v1);
std::cout << "v3=v1+v2 =\n";
display(v3);
std::cout << "produit matriciel de v3 et v2 :\n";
display(v3^v2);
// construction d'un Array2D initialisé à 1
Array2D<int> v4(7,5,1);
std::cout << "v4 :\n";
display(v4);
size_t size=std::min( v4.row(), v4.col() );
v4.resize( size, size );
std::cout << "v4 est maintenant carré :\n";
display(v4);
std::cout << "chargement de la matrice identité dans v4 :\n";
v4.setIdentity();
display(v4);
std::cout << "incrementation de v4 :\n";
display(++v4);
// appel d'une fonction prenant en parametre un pointeur
// pour c-style array
std::cout << "la valeur max de v1 est : "
<< MaxValue( v1.c_array(), v1.size() ) << '\n';
// creation std::vector< std::vector<int> >
std::vector< std::vector<int> > vv1(10);
for(std::vector<int>::size_type i=0; i<vv1.size(); i++)
{
vv1[i].push_back(i);
vv1[i].push_back(2*i +1);
}
Array2D<int> v5(vv1);
display(v5);
// addition Arrray2D<int> + std::vector< std::vector<int> >
Array2D<int> v6=v5+vv1;
std::cout << "v6=v5+vv1 :\n";
display(v6);
// min et max
std::cout << "v6.min() = " << v6.min() << '\n';
std::cout << "v6.max() = " << v6.max() << '\n';
// tri
v6.sort();
std::cout << "\nv6 trie dans l'ordre croissant : \n";
display(v6);
v6.usort();
std::cout << "dans l'ordre decroissant :\n";
display(v6);
// transposée
std::cout << "transposee de v6 :\n";
display( v6.transpose() );
std::cout.flush();
std::cin.get();
}
Conclusion :
tous les operateurs surchargés doivent etre supportés par l'objet contenu (sauf ^ ) pour beneficier de toute les fonctionalités
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.