web-dev-qa-db-fra.com

Le meilleur moyen de diviser un vecteur en deux tableaux plus petits?

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

22
mightcouldb1

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.

55
Xeo

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());
2
iamantony

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.

2
Israel Unterman

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";
   }
}
0
R.Mazgutov