Binary_search 在 STL 集中查找 set 的成员函数?

Binary_search in STL set over set's member function find?

本文关键字:set 成员 函数 查找 集中 search STL Binary      更新时间:2023-10-16

为什么我们有两种类似上面的方法来搜索集合中的元素?

此外,find算法可以用于查找列表或向量中的元素,但如果这些算法提供成员函数以及成员函数的速度预计比通用算法快,会有什么害处?

为什么我们需要删除算法,并创建所有关于删除的戏剧?删除只会移动元素,然后使用删除来删除实际元素。。就像STL列表提供了一个成员函数remove一样,为什么其他容器不能只提供一个remove函数并使用它呢?

STL集合中的Binary_search覆盖集合的成员函数find
为什么我们有两种类似上面的方法来搜索集合中的元素?

二进制搜索返回一个boolset::find()以及迭代器。为了比较苹果和苹果,比较set::find()的算法是std::lower_bound(),它也返回迭代器。

您可以在由一对(正向/双向/随机访问)迭代器指定的任意排序范围上应用std::lower_bound(),而不仅仅是在std::set因此,拥有std::lower_bound()是合理的由于std::set恰好是一个排序范围,您可以调用

std::lower_bound(mySet.begin(), mySet.end(), value);

但是

mySet.find(value);

通话不仅更简洁,而且效率更高。如果你仔细研究std::lower_bound()的实现,你会发现类似std::advance(__middle, __half);的东西根据迭代器(无论是前向/双向/随机访问迭代器)的不同而具有不同的复杂性。在std::set的情况下,迭代器是双向的,并且推进它们具有线性复杂性,哎哟!相反,std::set::find()保证以对数时间复杂度执行搜索。底层实现(在libstdc++的情况下是一个红黑树)使它成为可能提供set::find()也是合理的,因为它比在std::set上调用std::lower_bound()更高效。

此外,find算法可用于查找列表或矢量,但这些提供成员功能会有什么害处以及成员函数预期将比泛型函数更快算法?

我不知道如何为列表或向量提供更快的成员函数,除非容器经过排序(或具有一些特殊属性)。

为什么我们需要删除算法并创建所有关于擦除的戏剧remove where remove只会移动元素,然后使用擦除删除实际元素。。就像STL列表提供成员一样函数remove为什么其他容器不能提供remove功能并完成它?

我能想到两个原因

是的,STL严重缺乏许多便利功能。当在整个容器上使用算法时,我经常觉得自己生活在一个开始到结束的地狱里;我经常证明我自己的包装可以接受容器,比如:

template <typename T>
bool contains(const std::vector<T>& v, const T& elem) {
return std::find(v.begin(), v.end(), elem) != v.end();
}

这样我就可以写

if (contains(myVector, 42)) { 

而不是

if (std::find(myVector.begin(), myVector.end(), 42) != myVector.end()) { 

不幸的是,你经常不得不自己滚动或使用助推。为什么?因为标准化是痛苦而缓慢的,所以标准化委员会专注于更重要的事情委员会中的人经常捐出他们的空闲时间,而他们的工作却得不到报酬。

现在,从向量中删除元素可能很棘手:你关心元素的顺序吗?你的元素是POD吗?您的例外安全要求是什么?

假设您不关心元素的顺序,并且希望删除第i个元素:

std::swap(myVector[i], myVector.back());
myVector.pop_back();

或者更简单:

myVector[i] = myVector.back(); // but if operator= throws during copying you might be in trouble
myVector.pop_back();

在带有移动语义的C++11中:

myVector[i] = std::move(myVector.back());
myVector.pop_back();

请注意,这些是O(1)操作,而不是O(N)操作这些是标准委员会留给您的效率和异常安全注意事项的示例提供成员函数和"一刀切"不是C++的方式。

说了这么多,我再说一遍,我希望我们有更多的便利功能;我理解你的问题。

我将回答您的部分问题。擦除-删除习语来自Scott Meye的《有效STL》一书。至于为什么remove()实际上并没有从容器中删除元素,这里有一个很好的答案,我只是复制了部分答案:

关键是要认识到remove()的设计目的不仅仅是处理容器,但在任意前向迭代器对上:这意味着实际上无法删除元素,因为任意迭代器对不一定具有删除元素的能力。

为什么STL列表提供了一个成员函数remove,为什么其他容器不能只提供一个移除函数并使用它?我认为这是因为该习惯用法比其他方法更有效地从连续内存容器中删除特定值。