Cómo convertir un vector a una matriz

352

¿Cómo convierto std::vector<double>a a double array[]?

ganuke
fuente
99
Un poco plantea la pregunta de por qué? Puede acceder a un vector como una matriz. ¿Qué hace una matriz que no hace un vector?
Michael Dorgan
96
@Michael El caso de uso típico que tengo es el uso de un vector en mi propio código y la necesidad de llamar a una función de terceros que toma una matriz
Michael Mrozek
77
La terminología que se arroja es confusa. Un puntero no es una matriz. ¿Queremos un puntero al primer elemento de una matriz, o una matriz?
GManNickG
77
absolutamente una pregunta real, bastante simple, fácil de interpretar también. por favor vuelva a abrir.
dbliss
10
"Un poco plantea la pregunta de por qué?" - Primero, mal uso de esa frase. En segundo lugar, es muy evidente por qué.
Jim Balter

Respuestas:

533

Hay un truco bastante simple para hacerlo, ya que la especificación ahora garantiza que los vectores almacenen sus elementos de forma contigua:

std::vector<double> v;
double* a = &v[0];
Michael Mrozek
fuente
29
@ganuke No estás copiando, estás haciendo un puntero que apunta a la matriz real que el vector está usando internamente. Si desea copiar la respuesta de GMan explica cómo
Michael Mrozek
44
@ganuke: ¿Qué es "la matriz"? Necesitas dar más información. ¿Cuál es el panorama general?
GManNickG
66
@ganuke No, solo necesitas un double*que apunte a los mismos datos. Esta respuesta funciona exactamente para ese caso
Michael Mrozek
66
@guneykayim El vector posee ese recuerdo, no deberías liberarlo
Michael Mrozek
23
std::vector<double> v; double* a = v.data();
sinoTrinity
148

¿Para qué? Necesita aclarar: ¿Necesita un puntero al primer elemento de una matriz o una matriz?

Si está llamando a una función API que espera lo primero, puede hacerlo do_something(&v[0], v.size()), donde ves un vector de doubles. Los elementos de un vector son contiguos.

De lo contrario, solo tiene que copiar cada elemento:

double arr[100];
std::copy(v.begin(), v.end(), arr);

Asegúrese de que no solo arrsea ​​lo suficientemente grande, sino que arrse llene, o de que tenga valores no inicializados.

GManNickG
fuente
15
Nota: use v.size () para obtener el número de elementos para la nueva matriz: double arr [v.size ()];
rbaleksandar
77
@rbaleksandar: Las matrices no pueden tener un tamaño de expresión no constante.
GManNickG
@GManNickG: Funciona pero creo que hay algunos malentendidos aquí. Imagine lo siguiente: tiene una clase con un montón de punteros de varios tipos que tienen que apuntar a matrices, que no se conocen en el momento en que define su clase y que luego se crean al vaciar varios vectores y usar su parámetro de tamaño para determinar cuánto espacio se va a usar. Otro ejemplo: una función simple void arrayTest (unsigned int arrSize), que crea una matriz (short arr [arrSize];) usando su parámetro de función para el tamaño.
rbaleksandar
1
@rbaleksandar Sin malentendidos; en C ++ 11 y anteriores, los tamaños de matriz deben ser expresiones constantes integrales. Su ejemplo de función es un uso común para VLA en C, pero solo es compatible con la extensión (no estándar) en C ++. Sin embargo, puede llegar a C ++ 14: stackoverflow.com/a/17318040/87234 . Pero a partir de ahora, simplemente no es una opción estándar.
GManNickG
1
@GManNickG Creo que @Jet está diciendo que si desea convertir un vector en una matriz, y tiene la intención de cambiar el tamaño de la matriz usando la size()función de la std:vectorque necesitará usar newo mallocpara hacer eso. Como ya se señaló (por usted) eso double arr[v.size()]no es válido. Usar un vector en lugar de nuevo es una buena idea, pero el punto principal de la pregunta es cómo puede convertir un vector en una matriz.
RyanP
17
vector<double> thevector;
//...
double *thearray = &thevector[0];

Se garantiza que esto funcione de manera estándar, sin embargo, existen algunas advertencias: en particular, tenga cuidado de usar solo thearraymientras thevectoresté dentro del alcance.

usuario168715
fuente
44
... y asegúrese de que el vector no lo sea empty(), de lo contrario, esto invocaría al temido UB.
sbi
13

Los vectores efectivamente son matrices debajo de la piel. Si tienes una función:

void f( double a[]);

puedes llamarlo así:

vector <double> v;
v.push_back( 1.23 )
f( &v[0] );

Nunca debería necesitar convertir un vector en una instancia de matriz real.


fuente
1
Creo que te referías f( &v[0] );a tu última línea
Michael Mrozek
10

En cuanto a std::vector<int> vecvec para obtener int*, puede usar dos métodos:

  1. int * arr = & vec [0];

  2. int * arr = vec.data ();

Si desea convertir cualquier tipo de Tvector a T* array, simplemente reemplace el anterior inta T.

Te mostraré por qué los dos anteriores funcionan, para una buena comprensión.

std::vector Es una matriz dinámica esencialmente.

Miembro de datos principal de la siguiente manera:

template <class T, class Alloc = allocator<T>>
class vector{
    public:
        typedef T          value_type;
        typedef T*         iterator;
        typedef T*         pointer;
        //.......
    private:
        pointer start_;
        pointer finish_;
        pointer end_of_storage_;

    public:
        vector():start_(0), finish_(0), end_of_storage_(0){}
    //......
}

El range (start_, end_of_storage_)es toda la memoria de matriz que asigna el vector;

El range(start_, finish_)es toda la memoria de matriz que utiliza el vector;

El range(finish_, end_of_storage_)es la memoria de la matriz de respaldo.

Por ejemplo, en cuanto a un vector vec. que tiene {9, 9, 1, 2, 3, 4} es un puntero como el siguiente.

ingrese la descripción de la imagen aquí

So &vec[0]= start_ (address.) (Start_ es equivalente a int * array head)

En c++11 la data()función miembro simplemente devuelve start_

pointer data()
{ 
     return start_; //(equivalent to `value_type*`, array head)
}
Jayhello
fuente
2

Podemos hacer esto usando el método data (). C ++ 11 proporciona este método.

Fragmento de código

#include<bits/stdc++.h>
using namespace std;


int main()
{
  ios::sync_with_stdio(false);

  vector<int>v = {7, 8, 9, 10, 11};
  int *arr = v.data();

  for(int i=0; i<v.size(); i++)
  {
    cout<<arr[i]<<" ";
  }

  return 0;
}
rashedcs
fuente
2
std::vector<double> vec;
double* arr = vec.data();
Toby
fuente
1

Si usted tiene una función, entonces es probable que tenga la siguiente: foo(&array[0], array.size());. Si logró entrar en una situación en la que necesita una matriz, entonces necesita refactorizar, los vectores son básicamente matrices extendidas, siempre debe usarlas.


fuente
-1

Puedes hacer algo como esto

vector <int> id;
vector <double> v;

if(id.size() > 0)
{
    for(int i = 0; i < id.size(); i++)
    {
        for(int j = 0; j < id.size(); j++)
        {
            double x = v[i][j];
            cout << x << endl;
        }
    }
}
Sakthi Vignesh
fuente
v [i] [j]; para 2d array
Sakthi Vignesh