C++ 如何将向量拆分为n“;几乎相等”;部分
我有一个问题,我想合并大量的图像使用ImageMagick的convert.exe,但在Windows下,我有一个8192字节长的命令行限制 我的解决方案是将任务拆分为更小的子任务,运行它们,然后执行将它们组合在一起的最终任务 我的想法是写一个函数,它取一个图像向量和一个整数,然后将向量分成n个子向量,所有子向量的部分几乎相等 举个例子,如果我想把11分为3组,那就是4-4-3 你能告诉我如何用C++来做吗?我的意思是,写一个函数C++ 如何将向量拆分为n“;几乎相等”;部分,c++,visual-studio-2010,boost,vector,iterator,C++,Visual Studio 2010,Boost,Vector,Iterator,我有一个问题,我想合并大量的图像使用ImageMagick的convert.exe,但在Windows下,我有一个8192字节长的命令行限制 我的解决方案是将任务拆分为更小的子任务,运行它们,然后执行将它们组合在一起的最终任务 我的想法是写一个函数,它取一个图像向量和一个整数,然后将向量分成n个子向量,所有子向量的部分几乎相等 举个例子,如果我想把11分为3组,那就是4-4-3 你能告诉我如何用C++来做吗?我的意思是,写一个函数 split_vec( const vector<image
split_vec( const vector<image> &images, int split )
split_vec(常量向量和图像,整数分割)
分裂是哪一个
另外,如果我不需要创建新的向量,只需迭代子部分,您能告诉我最有效的方法是什么吗?像std::string
的std::substr
函数一样
注意:我已经在项目中使用了Boost,因此如果Boost中有一些很好的工具,那么它非常适合我。要获得每个零件尺寸的基数,只需将总数除以零件数:11/3=3。很明显,有些部分需要大于这个值才能得到合适的总数,但这只是剩下的部分:11%3=2。现在你知道其中两个零件的尺寸是3+1,剩下的都是3。 或者,如果你想通过外壳
vec::const_iterator i = vec .begin ();
vec::const_iterator j = i + stride;
while (j < vec .end ()) {
do_range (i, j);
i = j;
j += stride;
}
do_range (i, vec .end ());
vec::const_迭代器i=vec.begin();
常量迭代器j=i+stride;
而(j
您可以使用迭代器来迭代问题的子部分。迭代器的用法类似于指向向量的元素的指针
您希望在图像上执行的操作可以作为一个函数来实现
using namespace std;
void do_some_work(vector<image>::iterator begin, vector<image>::iterator end) {
vector<image>::iterator i = begin ;
while(i != end) {
// do something using *i , which will be of type image
++i ;
}
}
使用名称空间std;
void做一些工作(向量::迭代器开始,向量::迭代器结束){
向量::迭代器i=开始;
while(i!=结束){
//使用*i做一些事情,它将是image类型
++一,;
}
}
您是否考虑过使用xargs
程序。这可能是问题的高级解决方案。您不必创建新的子向量,请使用以下方法:
size_t ProcessSubVec(const vector<Image>& images, size_t begin, size_t end)
{
// your processing logic
}
void SplitVec(const vector<Image>& images, int cnt)
{
size_t SubVecLen = images.size() / cnt,
LeftOvers = images.size() % cnt,
i = 0;
// Split into "cnt" partitions
while(i < images.size())
i += ProcessSubVec(images, i, i + SubVecLen + (LeftOvers-- == 0 ? 0 : 1));
}
size\u t ProcessSubVec(常量向量和图像、大小开始、大小结束)
{
//您的处理逻辑
}
void SplitVec(常量向量和图像,int cnt)
{
size\u t SubVecLen=images.size()/cnt,
剩菜=图像。大小()%cnt,
i=0;
//拆分为“cnt”分区
而(i
希望这有帮助。以下是我的解决方案:
template<typename T>
std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n)
{
std::vector<std::vector<T>> outVec;
size_t length = vec.size() / n;
size_t remain = vec.size() % n;
size_t begin = 0;
size_t end = 0;
for (size_t i = 0; i < std::min(n, vec.size()); ++i)
{
end += (remain > 0) ? (length + !!(remain--)) : length;
outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end));
begin = end;
}
return outVec;
}
模板
标准::向量拆分向量(常数标准::向量和向量,大小)
{
std::矢量输出向量;
size\u t length=vec.size()/n;
size\u t remain=vec.size()%n;
大小\u t begin=0;
尺寸=0;
对于(size_t i=0;i0)?(长度+!!(保持-):长度;
outVec.push_back(std::vector(vec.begin()+begin,vec.begin()+end));
开始=结束;
}
返回outVec;
}
您可以创建一个返回std::vector的模板
并接收要分割的向量和分割数。
使用for和迭代器非常简单
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
template<typename T>
std::vector< std::vector<T> > split(std::vector<T> vec, uint64_t n) {
std::vector< std::vector<T> > vec_of_vecs(n);
uint64_t quotient = vec.size() / n;
uint64_t reminder = vec.size() % n;
uint64_t first = 0;
uint64_t last;
for (uint64_t i = 0; i < n; ++i) {
if (i < reminder) {
last = first + quotient + 1;
vec_of_vecs[i] = std::vector<T>(vec.begin() + first, vec.begin() + last);
first = last;
}
else if (i != n - 1) {
last = first + quotient;
vec_of_vecs[i] = std::vector<T>(vec.begin() + first, vec.begin() + last);
first = last;
}
else
vec_of_vecs[i] = std::vector<T>(vec.begin() + first, vec.end());
}
return vec_of_vecs;
}
#define ONE_DIMENSION 11
#define SPLITS 3
int main(void)
{
std::vector<uint64_t> vector(ONE_DIMENSION);
std::iota(std::begin(vector), std::end(vector), 1);
std::vector<std::vector<uint64_t>> vecs(SPLITS);
vecs = split(vector, SPLITS);
for (uint64_t m = 0; m < vecs.size(); ++m) {
for (auto i : vecs[m])
std::cout << std::setw(3) << i << " ";
std::cout << std::endl;
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
模板
std::vectorsplit(std::vector vec,uint64\n){
向量的std::vectorvec(n);
uint64_t商=向量大小()/n;
uint64\u t提醒=向量大小()%n;
uint64_t first=0;
uint64最后一次;
对于(uint64_t i=0;i std::我可以使用“unix”吗我的Windows机器上一直有实用程序。签出:unxutils.sf.net和/或www.cygwin.com谢谢你的提示,尽管我担心这不会帮助他在别人的计算机上运行代码:-PWhy?xargs
是一个独立的程序。与他的程序一起分发。谢谢,下面是我想到的:double loop=number/parts;for(int i=0;inumber
和parts
都是整数,那么在进行除法之前,您需要将1转换为double。此外,您还需要担心舍入错误,在某些情况下,当您转换回整数时,可能会出现一个off by一的错误。实际上,我在函数定义中使用了double和round()函数的开始和结束。你认为使用round()函数时可能会有舍入错误吗?(我使用stringstream进行舍入)@zsero,如果你对开始和结束使用舍入而不是截断,你应该可以。你之前的评论没有提到这一部分。Brandon ProcessSubVec应该返回什么?我不明白。