2012-12-23 10 views
5
int dArray[1600][32]; 
vector < vector <int> > dVector; 

n= 1600; k = 32 
dVector.resize(n); 
for(int i = 0 ; i < n ; ++i){ 
dVector[i].resize(k); 
} 

std::copy (dArray, dArray + tmp_c, std::back_inserter (dVector)); 

Come si usa la funzione std :: copy (o qualsiasi altra funzione) per copiare un array multidimensionale in un vettore e viceversa?Copia array multidimensionale per il vettore e viceversa

risposta

2

Non è possibile farlo direttamente, ma con un passaggio intermedio. A seconda delle tue esigenze, qualcosa del genere vector_wrapper potrebbe funzionare per te

#include <vector> 

template<typename T, int N> struct vector_wrapper { 
    vector_wrapper(T (&a)[N]) { 
     std::copy(a, a + N, std::back_inserter(v)); 
    } 

    std::vector<T> v; 
}; 

int dArray[1600][32]; 
std::vector<vector_wrapper<int, 32> > dVector; 

int main(int argc, char **argv) 
{ 
    std::copy(dArray, dArray + 1600, std::back_inserter(dVector)); 
    return 0; 
} 
+0

Grazie, questo ha funzionato perfettamente. –

+0

Come si stampa dVector? – chefarov

+0

@chefarov Il metodo più semplice potrebbe essere annidato per loop, o forse definire un operatore di output per 'vector_wrapper' e quindi stampare il' vector' più esterno. –

0

Dovrai scrivere il tuo iteratore che, su dereferenziamento, produce un oggetto helper che, dopo l'assegnazione, copia un array unidimensionale in un vettore con std::copy (e per copiare nella direzione opposta, un altro iteratore che esegue l'opposto). In pratica, dai un'occhiata al modo in cui è implementato lo standard back_insert_iterator e fai praticamente la stessa cosa, solo invece dichiama std::copy.

Personalmente penso che non ne valga la pena. Vorrei solo usare un ciclo for per la copia esterna. Ne hai già uno, basta aggiungere std::copy al suo corpo, subito dopo lo resize.

Si noti che se si dispone di resize i vettori in anticipo, non è necessario std::back_inserter in quanto allocerà ancora più spazio di archiviazione. Utilizzare invece begin.

1

Fondamentalmente è necessario scrivere il proprio tipo di output iterator. E 'un po' brutto, ma qualcosa di simile dovrebbe fare il trucco:

#include <vector> 
#include <algorithm> 
#include <iostream> 
#include <iterator> 

template <typename ContainerOfContainer, typename Container, std::size_t n> 
struct nested_back_inserter : public std::iterator<std::output_iterator_tag, void, 
                void, void, void> 
{ 
    std::size_t k; 
    std::size_t current_; 
    ContainerOfContainer* container_; 

    explicit nested_back_inserter(ContainerOfContainer& cont) 
    : k(0), current_(0), container_(&cont) 
    { } 

    nested_back_inserter& operator=(typename Container::value_type value) 
    { 
     if(k == n) { 
      ++current_; 
      k = 0; 
     } 
     (*container_)[current_].push_back(value); 
     ++k; 
     return *this; 
    } 

    nested_back_inserter& operator*() 
    { 
     return *this; 
    } 

    nested_back_inserter& operator++() 
    { 
     return *this; 
    } 

    nested_back_inserter& operator++(int) 
    { 
     return *this; 
    } 
}; 

int main() 
{ 
    int arr[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}}; 
    std::vector<std::vector<int>> v; 

    for(unsigned i = 0; i < 3; ++i) { 
     std::vector<int> vi; 
     v.push_back(vi); 
    } 

    typedef std::vector<std::vector<int>> nested; 
    typedef std::vector<int> cont; 
    std::copy(arr[0], arr[2] + 3, nested_back_inserter<nested, cont, 3>(v)); 

    for(auto it = v.begin(); it != v.end(); ++it) { 
     std::cout << "{"; 
     for(auto it2 = it->begin(); it2 != it->end(); ++it2) { 
       std::cout << *it2 << ", "; 
     } 
     std::cout << "}\n"; 
    } 

    return 0; 
} 

noti in particolare l'uglyness in std::copy(arr[0], arr[2] + 3, ...);.

A causa della stanchezza, non mi assumo alcuna responsabilità per errori off-by-one o altre stranezze che potrebbero verificarsi con questo. Dovrebbe darti un'idea di come implementare qualcosa come questa comunque.

Problemi correlati