web-dev-qa-db-ger.com

Wie kann man einen Vektor in zwei kleinere Arrays aufteilen?

Was ich versuche zu tun:

Ich versuche, einen Vektor in zwei separate Arrays aufzuteilen. Der aktuelle int-Vektor enthält ein Element pro Zeile in einer Textdatei. Die Textdatei ist eine Liste von zufälligen Ganzzahlen. 

Wie plane ich das zu tun:

Meine aktuelle Idee ist, zwei reguläre int-Arrays zu erstellen, dann den gesamten Vektor zu durchlaufen und n/2 -Elemente in jedes der Arrays zu kopieren.

Was ich gerne wissen würde:

Was ist der eleganteste Weg, meine Aufgabe zu erfüllen? Ich habe das Gefühl, dass ich dies tun kann, ohne den Vektor mehrmals zu durchlaufen.

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;
}

Vielen Dank :)

22
mightcouldb1

Verwenden Sie Iteratoren.

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

Da Iteratorbereiche halboffene Bereiche [begin, end) darstellen, müssen Sie dem zweiten Anfangsiterator keine 1 hinzufügen: lines.begin() + half_size wird nicht in den ersten Vektor kopiert.


Beachten Sie, dass Dinge wie 

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

Sind nicht Standard C++ (und somit nicht portabel). Dies sind sogenannte Arrays mit variabler Länge (kurz VLAs) und sind eine Sache von C99. Einige Compiler haben sie als Erweiterung beim Kompilieren von C++ - Code (GCC, Clang). Kompilieren Sie immer mit -pedantic, um eine Warnung zu erhalten. Diese VLAs wirken unkonventionell für Nicht-POD-Typen und sind im Allgemeinen nicht nützlich, da sie nicht einmal zurückgegeben werden können.

55
Xeo

Wenn Sie Code aus Xeo answer aufgrund strenger Compilerregeln nicht verwenden können oder generischere Methoden verwenden möchten, versuchen Sie 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

Wenn Sie nur einen Verweis auf die Zahlen benötigen, ohne sie zu ändern, können Sie Folgendes tun:

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

array_1 und array_2 sind eigentlich Zeiger auf den Anfang und die Mitte des Vektors. Dies funktioniert, da STL garantiert, dass Vektoren ihre Elemente in einem Dauerspeicher speichern. Beachten Sie, dass der Verweis auf lines.begin () nicht dafür verwendet werden kann.

2
Israel Unterman

Lösung zur Aufteilung des Vektors in Teile mit variabler Zählung mithilfe eines Iterators.

#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