2009-12-02 12 views
18

Je souhaite créer un tableau 2D en utilisant un vecteur. Mais, quand je fais cela, je me retrouve en faute. Quelqu'un peut-il s'il vous plaît expliquer ce que je fais mal, et une solution possible pour ce problème.Tableau bidimensionnel utilisant un vecteur

J'ai rendu tout public parce que je ne veux plus traiter avec les getters et les setters maintenant. Je veux que le concept de tableau 2D soit clair.

#include <iostream> 
#include <vector> 
using namespace std; 

class point 
{ 
    public: 
     point():x(0),y(0){} 
     ~point(){} 
     point(float xx,float yy):x(xx),y(yy){} 
     float x,y; 
}; 

int main() 
{ 
    vector<vector<point> > a; // 2D array 
    point p(2,3); 
    a[0][0] = p; // error here 
    return 0; 
} 
+1

Mais x et y doivent être publics. Il n'y a pas d'invariant sur le point qui exigerait que les membres soient privés. L'ajout de get_x, get_y, set_x et set_y rendrait toute fonction mathématique sur des points presque impossible à lire. –

Répondre

40

Votre vecteur est vide. Donc, vous ne pouvez pas utiliser [0][0].

Voici comment vous déclarez:

a.push_back(vector<point>()); 
a[0].push_back(p); 

Si vous savez combien d'articles que vous aurez dès le départ, vous pouvez le faire:

vector<vector<point> > a(10, vector<point>(10)); 

Il est un vecteur contenant 10 des vecteurs contenant 10 point. Ensuite, vous pouvez utiliser

a[4][4] = p; 

Cependant, je crois que l'utilisation de vecteur de vecteurs est source de confusion. Si vous voulez un tableau, pensez à utiliser uBLAS http://www.boost.org/doc/libs/1_41_0/libs/numeric/ublas/doc/index.htm

#include <boost/numeric/ublas/matrix.hpp> 
#include <boost/numeric/ublas/io.hpp> 

int main() { 
    using namespace boost::numeric::ublas; 
    matrix<double> m (3, 3); 
    for (unsigned i = 0; i < m.size1(); ++ i) 
     for (unsigned j = 0; j < m.size2(); ++ j) 
      m (i, j) = 3 * i + j; 
    std::cout << m << std::endl; 
} 
+1

merci, et pour plus d'informations, c'était utile :) – Curious

+7

Si vous avez votre réponse, marquez-le comme tel. Sinon, indiquez quel informatino supplémentaire vous avez besoin;) –

3

Vous créez votre tableau 2D très bien. Le problème est que lorsque vous le créez, c'est un tableau vide - il ne contient aucun point pour le moment. Vous essayez de utiliser le point à [0] [0] avant d'y avoir réellement créé un point. Normalement, pour mettre un nouvel élément dans un vecteur, vous devez utiliser resize() pour définir la taille du vecteur, ou push_back() pour ajouter des éléments un à la fois. Dans ce cas, ce dernier sera probablement un peu maladroit - puisque vous avez un vecteur de vecteurs de point, vous devez créer un vecteur de point, pousser un point sur ce vecteur, puis pousser ce vecteur sur votre tableau.

7

Vous avez construit un vecteur de vecteurs vide et vous avez essayé de déréférencer le premier élément sans y ajouter d'éléments.

Les vecteurs ne fonctionnent pas comme (certains) tableaux associatifs, où tenter d'accéder à une valeur manquante l'ajoutera à la collection. Vous devez vous assurer que les vecteurs ont un nombre approprié d'entrées avant d'essayer d'y accéder en utilisant la forme appropriée du constructeur de vecteur ou en utilisant push_back.

12

Voici une autre suggestion. Ce que vous essayez d'accomplir a été fait auparavant et peut être trouvé dans le Boost Multi-Array.

0

Vous pouvez définir vectorMatrix [] [], qui est une matrice de vecteurs comme suit.

Classe:

class vectorMatrix 
{ 
    std::vector<object> **cell; 

    int columns; 
    int rows; 

    public: 
    vectorMatrix(int columns, int rows); 
    virtual ~vectorMatrix(); 

    void addCellAt(int row, int column, const object& entry); 

    virtual std::vector<object>* getCell(int row, int column); 

    void clearMatrix(); 
}; 

Définir constructeur:

vectorMatrix::vectorMatrix(int columns, int rows) 
{ 
    this->columns = columns; 
    this->rows = rows; 

    cell = new std::vector<object>* [columns]; 

    for (int i = 0; i < columns; i++) 
    { 
     cell[i] = new std::vector<object>[rows]; 
    } 
} 

Procédé pour ajouter une entrée:

void vectorMatrix::addCellAt(int row, int column, const object& entry) 
{ 
     cell[channel][timeSlot].push_back(entry); 
} 

Obtention d'un pointeur sur le vecteur dans une rangée donnée et de la colonne:

std::vector<object>* vectorMatrix::getCell(int row, int column) 
{ 
    return &cell[row][column]; 
} 

Effacement de toute la matrice:

void vectorMatrix::clearMatrix() 
{ 
    for (int tmpRow = 0; tmpRow < columns; tmpRow ++) 
    { 
     for(int tmpColumn = 0; tmpColumn < rows; tmpColumn ++) 
     { 
      cell[tmpRow][tmpColumn].clear(); 
     } 
    } 
} 
1

a réussi à le faire fonctionner. Ramassé l'idée du «typedef» d'ailleurs. Essayez le code ci-dessous, cela fonctionne:

#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 
#include <vector> 


using namespace std; 

int main() 
{ 
    int i = 0; 
    int j = 0; 

/////////////////////////////////////////////////////////// 

    typedef vector<string> vecRow; 
    typedef vector<vecRow> vecCol; 

    vecRow vr; 
    vecCol vc; 
/////////////////////////////////////////////////////////// 
// Assigning string elements to the 2d array 

    for(i=0;i<10;i++) 
    { 
      for(j=0;j<5;j++) 
      { 
       vr.push_back("string ["+to_string(i)+"]["+to_string(j)+"]"); 
      } 
      vecRow vr_temp = vecRow(vr); 
      vc.push_back(vr_temp); 
      vr.clear(); 
    } 

/////////////////////////////////////////////////////////// 
// Printing back the elements from the 2D array 

    for(auto element : vc) 
    { 
      for(unsigned int ictr = 0;ictr < element.size() ; ictr++) 
      { 
       cout<<element[ictr]<<"\t"; 
      } 
      cout<<endl; 
    } 

    getchar(); 
    return 0; 
} 
0

Vous pouvez utiliser resize(); par exemple, ici, je remets à la côte a à 100 x 200 tableau:

vector<vector<point> > a; // 2D array           
    a.resize(100); 
    for_each(a.begin(),a.end(),[](vector<point>& v){v.resize(200);}); 
    point p(2,3); 
    a[0][0] = p; // ok now              
+1

La même chose est accomplie en construisant «vecteur > a (100, vecteur (200));' – Kundor

+0

ou 'vecteur > a (100); pour (auto & v: a) v.resize (200); ' – Kundor

+0

Existe-t-il un moyen de définir dynamiquement la taille d'un' std :: array' - peut-être avec des templates? 'template structure A {tableau , h> a;};' – wcochran

0

La façon la plus simple serait d'utiliser la méthode resize() comme suit:

vector <vector<int>> v; 
cin>>n>>m; //n is rows and m is columns 
v.resize(n,vector<int>(m)); 
for(i=0;i<n;i++)  // inserts elements into the vector v 
for(j=0;j<m;j++) 
    cin>>v[i][j]; 

for(i=0;i<n;i++)  //accesses elements of vector v 
for(j=0;j<m;j++) 
    cout<<v[i][j]<<" "; 
+0

il devrait être vecteur > .Laisser l'espace entre 2> sinon il y a une erreur – 97amarnathk

+0

L'erreur peut être vu –

+0

Oui, mais en tant que programmeur, il est de votre responsabilité d'écrire du code indépendant du compilateur – 97amarnathk

-1

La façon la plus simple d'utiliser vecteur sous forme de tableau de style C

int z =0; 
vector<vector<int>> vec(5,5); 
for(int i =0; i < 5; i++) 
{  
    for(int j=0; j<5; j++) 
    { 
     vec[i][j] = ++z; 
    } 
} 


for(int i =0; i < x; i++) 
{ 

    for(int j=0; j<x; j++) 
    { 
     cout<<vec[i][j]<<" "; 
    } 

} 
+0

Bien que ce soit sur les bonnes lignes pour un exemple simple, il ne compilera pas. 'vector > vec (5,5); 'ne correspond pas à un constructeur std :: vector approprié (voir http://en.cppreference.com/w/cpp/container/vector/vector). Il va essayer de créer le vecteur externe de taille 5 initialisé avec la valeur 5.Vous avez besoin de quelque chose comme 'vector > vec (5, vector (5));'. Enfin, votre 'x' devrait aussi être' 5'. –

Questions connexes