begin process at 2012 02 08 10:11:29
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > TABLEAU 2D GENERIQUE MATRICE...

TABLEAU 2D GENERIQUE MATRICE...


 Information sur la source

Note :
8 / 10 - par 1 personne
8,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :15/05/2004 Date de mise à jour :19/05/2004 00:30:42 Vu / téléchargé :10 736 / 448

Auteur : djl

Ecrire un message privé
Commentaire sur cette source (19)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
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

  • // 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();
  • }
// 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

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip COS ET SIN PLUS RAPIDE QUE MATH.H
Source avec Zip Source avec une capture [C++/DEVCPP] EXPLORATEUR EN OPENGL
Source avec Zip CLASSE PILE&TABLEAU GENERIQUE
Source avec Zip Source avec une capture PETIT DOOM LIKE EN OPENGL [VC++]
Source avec Zip Source avec une capture LABYRINTHE 3D [OPENGL/VISUAL C++ 6.0]

 Sources de la même categorie

Source avec Zip UN EXAMPLE D'APPLICATION EN CUDA DE L'ALGORITHME DE SCAN POU... par oguzaras
Source avec Zip Source avec une capture CHIFFREMENT DE VIGENERE par lajouad
Source avec Zip Source avec une capture ANALYSE SYNTAXIQUE par lajouad
Source avec Zip Source avec une capture STRUCTURE D'UNE MATRICE PAR LES LISTE LINÉAIRE (NON CONTUGUS... par benzarabel
Source avec Zip Source avec une capture DESSINER UNE ARBRE BINAIRE( MODE CONSOLE): par benzarabel

Commentaires et avis

Commentaire de vecchio56 le 16/05/2004 21:12:41 administrateur CS

qu'est ce que tu entends par 'canonique'?

Commentaire de djl le 16/05/2004 21:16:14

redefinition constructeur par defaut, constructeur par copie et operateur =, c'est benin mais malheuresement on c'est souvent oublié

Commentaire de Hylvenir le 18/05/2004 22:39:33

Salut,
pourquoi ( ou as-tu esssayé ) n'utilises-tu pas un simple vector pour insérer les éléments de ton tableau ?
Ta matrice n'étant plus qu'une couche une dessus du vecteur pour accèder au vecteur grâce aux deux dimensions ?

Commentaire de djl le 18/05/2004 22:53:42


pour l'instant c'est provisoir, mais au finale je n'utiliserait pas vector, au niveau performance yorai une perte

Commentaire de Hylvenir le 18/05/2004 22:56:08

Sur quelle taille de matrice comptes tu utiliser ta matrice, en général vector est optimisé et fonctionnement très bien pour des tailles raisonnables quand même.

Commentaire de djl le 18/05/2004 23:04:51


optimiser sans doute, j'avait deja fait des test sur un tableau 1 dimension de quelque millier d'element et j'etais quand meme 50% plus rapide

cette classe est souple, on peut l'utiliser aussi bien comme un tableau  ou comme une matrice, pour matrice je sais pas encore mais ca peut aller de 3x3, 4x4 à beaucoup plus (je me reserve cette possibilité

Commentaire de Hylvenir le 18/05/2004 23:07:56

50% ? avec la STL de Visual C++ 6.0 ?
Ca compte pas si oui, il faut en utiliser une autre que cette erreur de programmation.
Je ferais des essais pour voir avec la code que tu avais poster déjà sur un sujet similaire je crois.

Commentaire de djl le 18/05/2004 23:13:22

eu oui avec la stl de vc++6.0, remarque pour le moment je dev sous vc++6.0 mias je compte passer a dev c++
(j'ai test cette classe sous devc++, mais j'ai pas encore comparer avec vector..) tu pense que ca sera plu rapide avec vector?

Commentaire de Hylvenir le 18/05/2004 23:17:10

oui sûrement, tu devrais poster les tests pour faire des tests de performance, je les effectuerai chez moi avec plusieurs compilo et on pourra comparer le rapport performance/temps de codage.
J'ai déjà télécharger ta source que je regarderai demain sous linux.

Commentaire de djl le 18/05/2004 23:28:07

ben j'ai deja fait ca

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;ctime&gt;

#include "Array2D.h"


int main()
{
    const std::size_t SIZE=1000000;
    unsigned beg, end;
    
    std::vector&lt;int&gt; v_tab(SIZE);
    Array2D&lt;int&gt; a_tab(SIZE,1);
    
    beg=std::clock();
    for(std::vector&lt;int&gt;::size_type i=0; i&lt;v_tab.size(); i++)
    {
        v_tab[i]=5;
    }
    end=std::clock()-beg;
    std::cout &lt;&lt; end &lt;&lt; '\n';
    
    beg=std::clock();
    for(std::size_t i=0;  i&lt;a_tab.size(); i++)
    {
        a_tab[i]=5;
    }
    end=std::clock()-beg;
    std::cout &lt;&lt; end &lt;&lt; '\n';
    
    std::cout.flush();
    std::cin.get();
}

resultat j'obtient 190 pour vector et 20 pour Array2D ??
je doit mal m'y prendre  ? ca me paraity enorme comme difference, je vois pas comment vector pourrait etre aussi lent ?

si tu regarde le source hesitee pas a me dire si ya des erreurs, je repete c'est tout a fait possible

Commentaire de Hylvenir le 18/05/2004 23:31:10

Je vais regarder ça...

Sinon, tout le monde fait des erreurs [;)]

Commentaire de djl le 18/05/2004 23:34:52

vi, c'est pour ca que je poste

et aussi je vais rajouterune methode qui retourne le determinant, puis l'inverse de la matrice, mais si ta des idee n'hesite pas

Commentaire de Hylvenir le 18/05/2004 23:47:16

Juste ce changement pour la boucle du vector....je passe de 190 à 70

    std::vector&lt;int&gt;::size_type taille = v_tab.size();
    for(std::vector&lt;int&gt;::size_type i=0; i&lt; taille; ++i )
    {
        v_tab[i]=5;
    }

puis un simple -O3 sur g++ ramène les deux à 10.

Commentaire de djl le 18/05/2004 23:54:53

ok merci c'est noté


pour me decider j'aurais voulu que vector soit plus rapide, enfin je vais continuer à faire des test

Commentaire de djl le 19/05/2004 00:32:59

ouai ba en fait ta raison, vector est plus rapide, meme si la c'est pas encore totalement optimiser je pense que vector est la meilleur solution

mais en fait ma classe va en quelque sorte encapsuler un vector?

Commentaire de Hylvenir le 19/05/2004 09:34:51

Sinon pour le vecto, le fill_n rend le vector encore un peu plus rapide.


'Encapsuler' ? oui c'est une façon de le dire.On pourrait dire 'implémenter à l'aide' de aussi. Mais la POO est trop compliquée pour moi ;-)


PS :passée une certaine heure faut faire dodo :-)

Commentaire de djl le 19/05/2004 20:43:42

en fait le plus simple c'est de remplacer Type *values
par std::vector&lt;Type&gt; values; et ca va faire qd meme un surcouche de vector, mais ca sera toujours mieux puis que plus rapide, et ca simplifira

je dois me servir de fill_n, pour initialiser, et pour autre chose aussi?

Commentaire de Hylvenir le 19/05/2004 22:49:23

J'ai pas tout lu mais, ton code devrait se simplifier.
regarde la std::stack qui est sûrement un bonne exemple d'une utilisation d'une couche au dessus d'un vecteur

Commentaire de djl le 19/05/2004 22:57:12

ok merci, je vai aller voir

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,640 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales