Tableau 2d generique matrice...

Description

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

Codes Sources

A voir également

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.