如何将矢量分成n个“几乎相等”的部分

时间:2011-07-28 14:57:15

标签: c++ visual-studio-2010 boost vector iterator

我有一个问题,我想使用ImageMagick的convert.exe合并大量图像,但在Windows下我有8192字节长的命令行限制。

我的解决方案是将任务拆分为较小的子任务,运行它们,并执行将它们组合在一起的最终任务。

我的想法是编写一个函数,它接受一个图像矢量和一个整数,并将矢量分成n个子矢量,所有子矢量都具有“几乎相等”的部分。

因此,例如,如果我想将11分成3组,则为4-4-3。

你能告诉我怎样才能用C ++做到这一点?我的意思是,写一个函数

split_vec( const vector<image> &images, int split )

进行拆分?

另外,你能告诉我什么是最有效的方法如果我不需要创建新的向量,只需遍历子部分?与std::substr的{​​{1}}函数一样?

注意:我已经在项目中使用了Boost,所以如果在Boost中有一些不错的工具,那么它对我来说是完美的。

7 个答案:

答案 0 :(得分:11)

要获得每个零件尺寸的基数,只需将总数除以零件数量:11/3 = 3.显然,某些零件需要大于该零件才能得到合适的零件,但是那就是余数:11%3 = 2.所以现在你知道其中2个部分的大小是3 + 1,剩下的就是3个。

答案 1 :(得分:5)

这是我的解决方案:

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

答案 2 :(得分:1)

您是否考虑过使用xargs计划。这可能是解决问题的高级解决方案。

答案 3 :(得分:1)

您不必创建新的子矢量,使用以下内容:

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

希望这有帮助。

答案 4 :(得分:0)

CreateProcess has a 32kb limit

或者,如果你想通过shell,

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

答案 5 :(得分:0)

您可以使用iterators来迭代问题的子部分。迭代器的用法类似于指向vector

元素的指针

您想要对图像执行的操作可以实现为函数

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

答案 6 :(得分:0)

您可以创建一个返回std :: vector&lt;的模板。 std :: vector&gt; 并接收您想要拆分的矢量和分割数。 使用for和iterator非常容易。

.mat-tab-label-container{
  .mat-tab-list{
    .mat-ink-bar {
      background-color: green
    }
  }
}

.mat-tab-label-active{
 color: green 
}