Cómo convertir un vector a una matriz


352

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


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

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.


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.


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.


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

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

2
std::vector<double> vec;
double* arr = vec.data();

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.


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

v [i] [j]; para 2d array
Sakthi Vignesh
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.