c++ - resueltos - ¿La mejor manera de dividir un vector en dos matrices más pequeñas?
vectores y matrices en c++ (4)
Lo que estoy tratando de hacer:
Estoy tratando de dividir un vector en dos matrices separadas. El vector int actual contiene un elemento por línea en un archivo de texto. El archivo de texto es una lista de enteros aleatorios.
Cómo estoy planeando hacerlo:
Mi idea actual es crear dos matrices int regulares, luego iterar sobre todo el vector y copiar n / 2 elementos en cada una de las matrices.
Lo que me gustaría saber:
¿Cuál es la forma más elegante de cumplir mi tarea? Tengo la sensación de que puedo hacer esto sin iterar sobre el vector varias veces.
Código:
#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;
}
Gracias :)
Si no puedes usar el código de la respuesta de debido a las estrictas reglas del compilador o quieres una forma más genérica, prueba 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());
Si solo necesitas una referencia a los números sin manipularlos, entonces puedes hacer:
int *array_1 = &lines[0];
int *array_2 = &lines[lines.size() / 2];
array_1 y array_2 son, en realidad, punteros al inicio y en la mitad del vector. Esto funciona ya que STL garantiza que los vectores almacenan sus elementos dentro de una memoria continua. Tenga en cuenta que referirse a lines.begin () no se puede usar para esto.
Solución para dividir el vector para contar partes variables utilizando iterador.
#include <iostream>
#include <vector>
int main()
{
// Original vector of data
std::vector<double> mainVec{1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0};
// Result vectors
std::vector<std::vector<double>> subVecs{};
// Start iterator
auto itr = mainVec.begin();
// Variable to control size of non divided elements
unsigned fullSize = mainVec.size();
// To regulate count of parts
unsigned partsCount = 4U;
for(unsigned i = 0; i < partsCount; ++i)
{
// Variable controls the size of a part
auto partSize = fullSize / (partsCount - i);
fullSize -= partSize;
//
subVecs.emplace_back(std::vector<double>{itr, itr+partSize});
itr += partSize;
}
// Print out result
for (const auto& elemOuter : subVecs)
{
std::cout << std::fixed;
for (const auto& elemInner : elemOuter)
{
std::cout << elemInner << " ";
}
std::cout << "/n";
}
}
Utilizar iteradores.
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());
Como los rangos de iteradores representan la mitad de los rangos abiertos [begin, end)
, no es necesario agregar 1 al segundo iterador de inicio: lines.begin() + half_size
no se copia al primer vector.
Tenga en cuenta que cosas como
int split = lines.size() / 2;
int arrayA[split];
int arrayB[split];
No son estándar C ++ (y como tal no son portátiles). Estas son las llamadas matrices de longitud variable (VLAs) y son una cosa de C99. Algunos compiladores los tienen como una extensión al compilar el código C ++ (GCC, Clang). Siempre compila con -pedantic
para obtener una advertencia. Estos VLAs actúan de forma novedosa para los tipos que no son POD y generalmente no son útiles, ya que ni siquiera puedes devolverlos.