Ce que j'essaie de faire:
J'essaie de scinder un vecteur en deux tableaux distincts. Le vecteur int actuel contient un élément par ligne dans un fichier texte. Le fichier texte est une liste d'entiers aléatoires.
Comment je compte le faire:
Mon idée actuelle est de créer deux tableaux réguliers int, puis de parcourir le vecteur entier et de copier les éléments n/2 dans chacun des tableaux.
Ce que j'aimerais savoir:
Quel est le moyen le plus élégant d'accomplir ma tâche? J'ai le sentiment que je peux le faire sans parcourir plusieurs fois le vecteur.
Code:
#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;
}
Je vous remercie :)
Utilisez des itérateurs.
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());
Étant donné que les plages d'itérateurs représentent les demi-plages ouvertes [begin, end)
, il n'est pas nécessaire d'ajouter 1 au deuxième itérateur de début: lines.begin() + half_size
n'est pas copié dans le premier vecteur.
Notez que des choses comme
int split = lines.size() / 2;
int arrayA[split];
int arrayB[split];
Ne sont pas des standards C++ (et ne sont donc pas portables). Ce sont ce qu'on appelle des tableaux de longueur variable (VLA) et sont un élément C99. Certains compilateurs les ont comme extension lors de la compilation de code C++ (GCC, Clang). Toujours compiler avec -pedantic
pour obtenir un avertissement. Ces VLA sont géniaux pour les types autres que POD et ne sont généralement pas utiles, car vous ne pouvez même pas les retourner.
Si vous ne pouvez pas utiliser le code de Xeo answer en raison de règles de compilateur strictes ou si vous voulez une méthode plus générique, essayez 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 vous avez seulement besoin d'une référence aux nombres sans les manipuler, vous pouvez faire:
int *array_1 = &lines[0];
int *array_2 = &lines[lines.size() / 2];
array_1 et array_2 sont en réalité des pointeurs vers le début et le milieu du vecteur. Cela fonctionne car STL garantit que les vecteurs stockent leurs éléments dans une mémoire continue. Notez que faire référence à lines.begin () ne peut pas être utilisé pour cela.
Solution pour fractionner le vecteur en nombre de pièces à l'aide d'un itérateur.
#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";
}
}