2012-03-21 18 views
19

Quello che sto cercando di fare:Il modo migliore per dividere un vettore in due array più piccoli?

Sto cercando di dividere un vettore in due array separati. Il vettore int attuale contiene un elemento per riga in un file di testo. Il file di testo è un elenco di numeri interi casuali.

Come ho intenzione di farlo:

La mia idea attuale è di creare due array int regolari, poi iterare su tutta vettoriale e copiare n/2 elementi a ciascuna delle matrici.

Quello che vorrei sapere:

Qual è il modo più elegante di compiere il mio compito? Ho la sensazione di poterlo fare senza scorrere il vettore più volte.

Codice:

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

vector<int> ifstream_lines(ifstream& fs) 
{ 
    vector<int> out; 
    int temp; 
    while(fs >> temp) 
    { 
    out.push_back(temp); 
    } 
    return out; 
} 

vector<int> MergeSort(vector<int>& lines) 
{ 
    int split = lines.size()/2; 
    int arrayA[split]; 
    int arrayB[split]; 
} 

int main(void) 
{ 
    ifstream fs("textfile.txt"); 
    vector<int> lines; 
    lines = ifstream_lines(fs); 

    return 0; 
} 

Grazie :)

+0

io consiglierei qualcosa dal '' intestazione (http://en.cppreference.com/w/cpp/algorithm). 'std :: copy' o' std :: move' potrebbe essere di interesse. –

+0

Mi piace come viene posta la domanda. Non vedi molto bene domande strutturate come questa da parte dei nuovi utenti. – MOnsDaR

+0

se non si prevede di modificare la dimensione dei 2 array, è possibile dare un'occhiata a 'array_view' – sp2danny

risposta

44

Utilizzare iteratori.

std::vector<int> lines; 
// fill 
std::size_t const half_size = lines.size()/2; 
std::vector<int> split_lo(lines.begin(), lines.begin() + half_size); 
std::vector<int> split_hi(lines.begin() + half_size, lines.end()); 

Dal gamme iteratore rappresentano intervalli [begin, end) socchiusa, non è necessario aggiungere 1 al iteratore secondo inizio: lines.begin() + half_size non viene copiato il primo vettore.


Si noti che le cose come

int split = lines.size()/2; 
int arrayA[split]; 
int arrayB[split]; 

non sono standard C++ (e come tale non portatile). Questi sono i cosiddetti array a lunghezza variabile (VLA in breve) e sono una cosa C99. Alcuni compilatori li hanno come estensione durante la compilazione del codice C++ (GCC, Clang). Compilare sempre con -pedantic per ricevere un avviso. Questi VLA agiscono in modo funky per i tipi non POD e generalmente non sono utili, dal momento che non è possibile restituirli.

+0

Risposta molto buona, +1 per" non è necessario aggiungere 1 al secondo iteratore iniziale " –

2

Se avete solo bisogno di un riferimento ai numeri senza manipolarli, allora si può fare:

int *array_1 = &lines[0]; 
int *array_2 = &lines[lines.size()/2]; 

array_1 e array_2 sono, in realtà, puntatori a l'inizio e la metà del vettore. Questo funziona poiché STL garantisce che i vettori memorizzino i loro elementi all'interno di una memoria continua. Nota che riferirsi a lines.begin() non può essere usato per questo.

1

Se non è possibile utilizzare il codice da Xeo risposta causa delle rigide regole del compilatore o si desidera modo più generico, provare std::advance:

#include <vector> 
#include <iterator> 

size_t middle = input.size()/2; 
std::vector<int>::const_iterator middleIter(input.cbegin()); 
std::advance(middleIter, middle); 

std::vector<int> leftHalf(input.begin(), middleIter); 
std::vector<int> rightHalf(middleIter, input.end()); 
Problemi correlati