2009-12-02 20 views
18

Quiero crear una matriz 2D usando vectores. Pero, cuando hago esto, obtengo seg fault. ¿Alguien puede explicar lo que estoy haciendo mal y la posible solución para este problema?Arrays bidimensionales usando el vector

Hice todo público, ya que no quiero tratar con getters y setters ahora. Quiero aclarar el concepto de matriz 2D.

#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

Pero x y y deberían ser públicos. No hay un punto invariable que requiera que los miembros sean privados. Agregar get_x, get_y, set_x y set_y haría que cualquier función matemática en puntos sea casi imposible de leer. –

Respuesta

40

Su vector está vacío. Entonces no puedes usar [0][0].

Así es como se declara:

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

Si sabe el número de elementos que tendrá desde el principio, que puede hacer:

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

Es un vector que contiene 10 vectores que contienen 10 punto. Entonces puede usar

a[4][4] = p; 

Sin embargo, creo que usar el vector de vectores es confuso. Si quieres una matriz, considerar el uso de 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

gracias, y para obtener información adicional, fue útil :) – Curious

+7

Si tiene su respuesta, márquela como tal. De lo contrario, indique qué información adicional necesita;) –

3

va a crear la matriz 2D muy bien. El problema es que cuando lo creas, es una matriz vacía, todavía no tiene ningún punto. Intenta utilizar el punto en [0] [0] antes de crear un punto allí. Normalmente, para poner un nuevo elemento en un vector, usa resize() para establecer el tamaño del vector, o push_back() para agregar elementos de a uno por vez. En este caso, este último probablemente sea un poco torpe: como tienes un vector de vectores de punto, necesitas crear un vector de punto, insertar un punto en ese vector y luego insertar ese vector en tu matriz.

7

Has construido un vector de vectores que está vacío y he intentado quitar la referencia al primer elemento sin agregarle ningún elemento.

Los vectores no funcionan como (algunas) matrices asociativas, cuando intenten acceder a un valor que falta lo agregará a la colección. Debe asegurarse de que los vectores tengan un número adecuado de entradas antes de intentar acceder a ellos utilizando la forma apropiada del vector constructor o utilizando push_back.

12

Aquí hay otra sugerencia. Lo que está tratando de lograr se ha realizado anteriormente y se puede encontrar en el Boost Multi-Array.

0

Puede definir vectorMatrix [] [], que es una matriz de vectores de la siguiente manera.

Clase:

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

Definir constructor:

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]; 
    } 
} 

un método para añadir una entrada:

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

Conseguir un puntero al vector en una fila y columna dada:

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

Borrado de toda la matriz:

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

arregló para conseguir que funcione. Recogió la idea del 'typedef' de otro lado. Pruebe el código de abajo, funciona:

#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

Usted puede utilizar resize(); por ejemplo, aquí puedo cambiar el tamaño a a una matriz de 100 x 200:

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

Lo mismo se logra construyendo 'vector > a (100, vector (200));' – Kundor

+0

O 'vector > a (100); for (auto & v: a) v.resize (200); ' – Kundor

+0

¿Hay alguna forma de establecer dinámicamente el tamaño de un' std :: array', quizás con plantillas? 'template struct A {array , h> a;};' – wcochran

0

La manera más sencilla sería utilizar resize() método como sigue:

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

debe ser el vector >. Deje espacio entre 2> de lo contrario hay un error. – 97amarnathk

+0

Se puede ver el error con algunos compiladores solamente. –

+0

Sí. Pero como programador, es su responsabilidad escribir código independiente del compilador. – 97amarnathk

-1

La forma más sencilla de utilizar vector como matriz de estilo 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

Si bien esto está en las líneas correctas para un ejemplo simple, no se compilará. 'vector > vec (5,5); 'no coincide con un constructor std :: vector adecuado (ver http://en.cppreference.com/w/cpp/container/vector/vector). Intentará crear el vector externo de tamaño 5 inicializado con el valor 5.Necesitas algo como 'vector > vec (5, vector (5));'. Por último, tu 'x' también debería ser' 5'. –

Cuestiones relacionadas