Подтвердить что ты не робот

Лучший способ разделить вектор на два меньших массива?

Что я пытаюсь сделать:

Я пытаюсь разбить вектор на два отдельных массива. Текущий вектор int содержит элемент в строке в текстовом файле. Текстовый файл представляет собой список случайных целых чисел.

Как я планирую это сделать:

Моя текущая идея состоит в том, чтобы создать два регулярных массива int, затем перебрать весь вектор и скопировать n/2 элементов на каждый из массивов.

Что я хотел бы знать:

Какой самый элегантный способ выполнить мою задачу? У меня такое чувство, что я могу сделать это без повторения вектора несколько раз.

Код:

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

Спасибо:)

4b9b3361

Ответ 1

Используйте итераторы.

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

Так как диапазоны итераторов представляют собой половину открытых диапазонов [begin, end), вам не нужно добавлять 1 ко второму итератору begin: lines.begin() + half_size не копируется в первый вектор.


Обратите внимание, что такие вещи, как

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

Не являются стандартными С++ (и как таковые не переносимы). Это так называемые массивы переменной длины (VLA для краткости) и являются C99. Некоторые компиляторы имеют их как расширение при компиляции кода С++ (GCC, Clang). Всегда компилируйте с помощью -pedantic, чтобы получить предупреждение. Эти VLA действуют фанки для не-POD-типов и обычно не полезны, поскольку вы даже не можете их вернуть.

Ответ 2

Если вам нужна только ссылка на номера без их манипулирования, вы можете сделать:

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

array_1 и array_2 на самом деле указывают на начало и середину вектора. Это работает, поскольку STL гарантирует, что векторы хранят свои элементы в непрерывной памяти. Обратите внимание, что ссылаться на lines.begin() нельзя использовать для этого.

Ответ 3

Если вы не можете использовать код из Xeo из-за строгих правил компиляции или хотите более общий способ, попробуйте 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());