1

我有一个向量,我想使用 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);
4

3 回答 3

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 中,你所拥有的可能是最好的。

于 2012-08-13T17:17:39.543 回答
1

如果您可以访问 c++11 编译器和可移动对象, std::move可以做得更好。

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

于 2012-08-13T17:08:42.483 回答
0

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

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

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

于 2012-08-13T17:09:58.693 回答