C++ 将向量拆分为两个较小数组的最佳方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9811235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:18:14  来源:igfitidea点击:

Best way to split a vector into two smaller arrays?

c++splitfstreamstdvector

提问by mightcouldb1

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. The text file is a list of random integers.

我试图将一个向量分成两个单独的数组。当前 int 向量在文本文件中每行包含一个元素。文本文件是一个随机整数列表。

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/2elements 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 :)

谢谢 :)

回答by Xeo

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_sizeisn'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). These are so-called variable-length arrays (VLAs for short) and are a C99 thing. Some compilers have them as an extension while compiling C++ code (GCC, Clang). Always compile with -pedanticto get a warning. These VLAs act funky for non-POD types and aren't generally useful, since you can't even return them.

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

回答by iamantony

If you can't use code from Xeoanswer 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());

回答by Israel Unterman

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. This works since STL guarantees that vectors store their elements within a continuous memory. Note that referring to lines.begin() can't be used for this.

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

回答by R.Mazgutov

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