我有一个向量,我想使用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);
答案 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)
std::move可以做得更好。
请注意,您仍需要从第一个矢量中删除它们。
答案 2 :(得分:0)
还有其他几种方法可以执行此任务,例如使用复制算法和插入迭代器。
但算法由于向量容器的性质,这些动作的复杂性将始终为O(n)。 Vector不是一个允许在O(1)(常数)时间内将大块数据从一个容器移动到另一个容器的列表。根据特定的STL实现,一种方式可以比另一种方式好10-20%,但不太可能超过它。
如果容器的数据类型允许移动语义并且您具有这些语言功能,这肯定会有所帮助。但这更多是关于处理容器中的数据对象而不是容器本身。