简体   繁体   English

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

[英]Best way to split a vector into two smaller arrays?

What I'm trying to do: 我正在尝试做什么:

I am trying to split a vector into two separate arrays. 我试图将一个矢量分成两个独立的数组。 The current int vector contains an element per line in a text file. 当前int向量包含文本文件中每行的元素。 The text file is a list of random integers. 文本文件是随机整数列表。

How I'm planning to do it: 我打算怎么做:

My current idea is to create two regular int arrays, then iterate over the entire vector and copy n/2 elements to each of the arrays. 我目前的想法是创建两个常规int数组,然后迭代整个向量并将n / 2个元素复制到每个数组。

What I would like to know: 我想知道的是:

What is the most elegant way of accomplishing my task? 完成任务的最优雅方式是什么? I have a feeling that I can do this without iterating over the vector multiple times. 我有一种感觉,我可以做到这一点,而无需多次迭代矢量。

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

Thank you :) 谢谢 :)

Use iterators. 使用迭代器。

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

Since iterator ranges represent half open ranges [begin, end) , you don't need to add 1 to the second begin iterator: lines.begin() + half_size isn't copied to the first vector. 由于迭代器范围代表半开放范围[begin, end) ,因此您不需要向第二个开始迭代器添加1: lines.begin() + half_size不会复制到第一个向量。


Note that things like 注意事情就好

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

Are not standard C++ (and as such not portable). 不是标准的C ++(因此不可移植)。 These are so-called variable-length arrays (VLAs for short) and are a C99 thing. 这些是所谓的可变长度数组(简称VLA),是C99的东西。 Some compilers have them as an extension while compiling C++ code (GCC, Clang). 一些编译器在编译C ++代码(GCC,Clang)时将它们作为扩展。 Always compile with -pedantic to get a warning. 始终使用-pedantic进行编译以获得警告。 These VLAs act funky for non-POD types and aren't generally useful, since you can't even return them. 这些VLA对非POD类型起作用,并且通常不常用,因为您甚至无法返回它们。

If you can't use code from Xeo answer due to strict compiler rules or you want more generic way, try std::advance : 如果由于严格的编译规则而无法使用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());

If you only need a reference to the numbers without manipulating them, then you can do: 如果您只需要对数字进行引用而不进行操作,那么您可以:

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

array_1 and array_2 are, actually, pointers to the start and middle of the vector. 实际上,array_1和array_2是指向矢量开始和中间的指针。 This works since STL guarantees that vectors store their elements within a continuous memory. 这是有效的,因为STL保证向量将它们的元素存储在连续的内存中。 Note that referring to lines.begin() can't be used for this. 请注意,引用lines.begin()不能用于此。

Solution to split vector to variable count parts using iterator. 使用迭代器将向量拆分为可变计数部分的解决方案。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM