将矢量分成两个较小数组的最佳方法是什么?

时间:2012-03-21 19:08:07

标签: c++ split fstream stdvector

我正在尝试做什么:

我正在尝试将矢量拆分为两个单独的数组。当前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;
}

谢谢:)

4 个答案:

答案 0 :(得分:58)

使用迭代器。

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:lines.begin() + half_size不会复制到第一个向量。


请注意

之类的内容
int split = lines.size() / 2;
int arrayA[split];
int arrayB[split];

不是标准C ++(因此不可移植)。这些是所谓的可变长度数组(简称VLA),是C99的东西。一些编译器在编译C ++代码(GCC,Clang)时将它们作为扩展。始终使用-pedantic进行编译以获得警告。这些VLA对非POD类型起作用,并且通常不常用,因为您甚至无法返回它们。

答案 1 :(得分:2)

如果您只需要参考数字而不操纵它们,那么您可以这样做:

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

array_1和array_2实际上是指向矢量开始和中间的指针。这是有效的,因为STL保证向量将它们的元素存储在连续的内存中。 请注意,引用lines.begin()不能用于此。

答案 2 :(得分:2)

如果由于严格的编译规则而无法使用来自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());

答案 3 :(得分:1)

使用迭代器将矢量拆分为可变计数部分的解决方案。

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