如何将矢量的后半部分移动到另一个矢量?

时间:2012-08-13 17:01:13

标签: c++ insert stdvector erase

我有一个向量,我想使用STL算法有效地将向量的后半部分分解为另一个向量。这是我看到的一种方法,但是期望有更有效和简洁的答案,或者至少是使用stl算法的答案:

std::vector<Entry> &entries = someFunction();
int numEntries = entries.size();

// Assume numEntries is greater than or equal to 2.

std::vector<Entry> secondEntries;
std::vector<Entry>::iterator halfway = entries.begin() + numEntries / 2;
std::vector<Entry>::iterator endItr  = entries.end() 

// Copy the second half of the first vector in the second vector:
secondEntries.insert(secondEntries.end(), halfway, endItr);

// Remove the copied entries from the first vector:
entries.erase(halfway, endItr);

3 个答案:

答案 0 :(得分:4)

退一步,请记住确保您使用自己的算法处理迭代器,而不是(必要)容器。所以如果你有这个:

void foo(const std::vector<Entry>& v) { /* ... */ }

现在你陷入了这种情况:

std::vector<Entry> entries = someFunction();

// have to split entries! make more containers? :(
foo(first_half(entries));
foo(second_half(entries));

请考虑使用迭代器:

// or a template, if it doesn't hurt
void foo(std::vector<Entry>::const_iterator first, 
         std::vector<Entry>::const_iterator second) { /* ... */ }

所以现在你表示范围而不是容器:

std::vector<Entry> entries = someFunction();

// easy to split entries! :)
auto middle = entries.begin() + entries.size() / 2;
foo(entries.begin(), middle);
foo(middle + 1, entries.end());

这限制了您所做的不必要的容器和分配的数量。


有了这个,在C ++ 11中你可以做到这一点(其余部分是相同的):

// *Move* the second half of the first vector in the second vector:           
secondEntries.insert(secondEntries.end(),
                        std::make_move_iterator(halfway),
                        std::make_move_iterator(endItr));

如果Entry有一个移动构造函数,move_iterator适配器将确保在插入过程中使用它(如果它没有进行正常复制)。在C ++ 03中,你所拥有的可能是最好的。

答案 1 :(得分:1)

如果您可以访问c ++ 11编译器和可移动对象,

std::move可以做得更好。

请注意,您仍需要从第一个矢量中删除它们。

答案 2 :(得分:0)

还有其他几种方法可以执行此任务,例如使用复制算法和插入迭代器。

但算法由于向量容器的性质,这些动作的复杂性将始终为O(n)。 Vector不是一个允许在O(1)(常数)时间内将大块数据从一个容器移动到另一个容器的列表。根据特定的STL实现,一种方式可以比另一种方式好10-20%,但不太可能超过它。

如果容器的数据类型允许移动语义并且您具有这些语言功能,这肯定会有所帮助。但这更多是关于处理容器中的数据对象而不是容器本身。