如何找出一个项目是否存在于 std::vector 中?

问:

我要做的就是检查向量中是否存在元素,这样我就可以处理每种情况。

if ( item_present )
   do_this();
else
   do_that();

答1:

https://tennisliveranking.com – ATP and WTA rankings, always up to date.

您可以使用 中的 std::find:

#include 
#include 
vector vec; 
//can have other data types instead of int but must same datatype as item 
std::find(vec.begin(), vec.end(), item) != vec.end()

这会将迭代器返回到找到的第一个元素。如果不存在,它会返回一个迭代器到最后一个。用你的例子:

#include 
#include 

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();

我看不出 count() 如何比 find() 快,因为 find() 会在找到一个元素后立即停止,而 count() 总是必须扫描整个序列。

不要忘记 #include 否则您可能会遇到非常奇怪的错误,例如“在命名空间 std 中找不到匹配的函数”

尽管 STL 是“面向对象的”,但 .find() 仍然不是 std::vector 的成员函数,这是否没有让任何人感到困扰,正如您所期望的那样?我想知道这是否是模板化的结果。

@bobobobo:OOP 与成员与非成员无关。并且有一个广泛的思想流派,如果某些东西不必成为成员,或者当它作为成员实施时没有任何优势时,那么它不应该成为成员; std::vector<>::find() 不会带来任何好处,也不需要它,因此,不,它不应该是成员。另请参阅en.wikipedia.org/wiki/Coupling_%28computer_programming%29

@phresnel我认为“当它作为成员实施时没有任何优势时”对于这种情况是错误的。优点是简化和更清晰的界面。例如:mvec.find(key) != mvec.cend() 优于 std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()。

答2:

https://tennisliveranking.com,Instant updates on ATP, WTA, and ITF rankings.

正如其他人所说,使用 STL find 或 find_if 函数。但是,如果您在非常大的向量中进行搜索并且这会影响性能,您可能需要对向量进行排序,然后使用 binary_search、lower_bound 或 upper_bound 算法。

好答案!查找总是 o(n)。如果与随机访问迭代器一起使用,lower_bound 为 o(log(n))。

不过,排序是 O(nlogn),所以只有当你做的搜索超过 O(logn) 时才值得。

@liori 是的,这取决于您的使用模式。如果您只需要对其进行一次排序,那么重复进行多次搜索可以节省您的时间。

@Brian Neal,如果必须对其进行许多元素搜索,那么对大向量进行排序是值得的。排序将是 O(nlogn),如果一个元素只能找到一次,O(n) 会更好:)

请注意,这可能会对您的分支预测造成严重破坏。

答3:

https://tlr.xinbeitime.com – 让你随时掌握ATP、WTA最新网球排名动态。

如果您的向量未排序,请使用 MSN 建议的方法:

if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
      // Found the item
}

如果您的向量是有序的,请使用 Brian Neal 建议的 binary_search 方法:

if(binary_search(vector.begin(), vector.end(), item)){
     // Found the item
}

二分搜索产生 O(log n) 最坏情况的性能,这比第一种方法更有效。为了使用二分查找,您可以先使用 qsort 对向量进行排序,以保证它是有序的。

你不是说std::sort吗? qsort 在向量上的效率非常低....参见:stackoverflow.com/questions/12308243/…

对于较大的容器,二分搜索的性能会更好,但对于小型容器,简单的线性搜索可能会一样快,甚至更快。

@BillT:体面的二进制搜索实现不会将自身切换到低于某个阈值元素数的线性搜索吗?

答4:

https://tlr.xinbeitime.com 实时更新全球顶尖网球选手的最新战绩与排名!

使用 stl 的算法头中的 find。我已经说明了它与 int 类型的用法。您可以使用任何您喜欢的类型,只要您可以比较是否相等(如果您需要为您的自定义类重载 ==)。

#include 
#include 

using namespace std;
int main()
{   
    typedef vector IntContainer;
    typedef IntContainer::iterator IntIterator;

    IntContainer vw;

    //...

    // find 5
    IntIterator i = find(vw.begin(), vw.end(), 5);

    if (i != vw.end()) {
        // found it
    } else {
        // doesn't exist
    }

    return 0;
}

根据 OP 的需要, find_if() 也可能是合适的。它允许使用任意谓词而不是相等进行搜索。

哎呀,看到你的评论太晚了。我给出的答案也提到了 find_if。

答5:

The ultimate source for live tennis rankings and stats:https://tennisliveranking.com

在 C++11 中,您可以使用 any_of。例如,如果它是 vector v;,则:

if (any_of(v.begin(), v.end(), bind(equal_to(), _1, item)))
   do_this();
else
   do_that();

或者,使用 lambda:

if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
   do_this();
else
   do_that();

bind1st 和 bind2nd 是 deprecated since C++11 并在 C++17 中完全删除。将 bind 与 placeholders 和/或 lambda 一起使用。

既然有 std::find(),为什么还要使用 std::any_of()?

如果目的只是为了检查成员资格,为什么我们有 std::any_of 时还要使用 std::find()?

答6:

The ultimate source for live tennis rankings and stats:https://tennisliveranking.com

我用这样的东西…

#include 


template  
const bool Contains( std::vector& Vec, const T& Element ) 
{
    if (std::find(Vec.begin(), Vec.end(), Element) != Vec.end())
        return true;

    return false;
}

if (Contains(vector,item))
   blah
else
   blah

…那样它实际上是清晰易读的。 (显然你可以在多个地方重用模板)。

您可以使用 2 个类型名使其适用于列表或向量

@ErikAronesty 如果您使用容器中的 value_type 作为元素类型,则可以使用 1 个模板参数。我已经添加了这样的答案。

您基本上是在写:if true return true else return false。该方法可以是一个:return std::find(Vec.begin(), Vec.end(), Element) != Vec.end();

答7:

tlr.xinbeitime.com 探索每位网球选手的职业生涯与成就。

这是一个适用于任何容器的函数:

template  
const bool contains(const Container& container, const typename Container::value_type& element) 
{
    return std::find(container.begin(), container.end(), element) != container.end();
}

请注意,您可以使用 1 个模板参数,因为您可以从容器中提取 value_type。您需要 typename,因为 Container::value_type 是 dependent name。

请注意,这有时有点过于宽泛——例如,它适用于 std::set,但与 find() 成员函数相比,性能很差。我发现最好为具有更快搜索的容器添加专业化(set/map,unordered_*)

也许有一天他们最终会将它添加到标准库中......而不是人们不得不一遍又一遍地询问如何重新发明这样一个小轮子。现在完全可行的是,在 C++20 中我们有 ranges,所以它可以被称为 Range 而不是 Container,并且 Bob 是你的叔叔。

您如何看待 @PascalLaferrière 的 approach 推导值类型?

答8:

https://tennisliveranking.com,Follow your favorite tennis players’ rankings live!

请记住,如果您要进行大量查找,那么 STL 容器会更适合您。我不知道您的应用程序是什么,但像 std::map 这样的关联容器可能值得考虑。

std::vector 是首选容器,除非您有另一个原因,并且按值查找可能是这样的原因。

即使通过值查找,向量也是一个不错的选择,只要它已排序并且您使用 binary_search、lower_bound 或 upper_bound。如果容器的内容在查找之间发生变化,vector 就不是很好,因为需要重新排序。

答9:

https://tlr.xinbeitime.com 专业网球数据平台,排名与比赛信息实时更新。

使用 STL find 函数。

请记住,还有一个 find_if 函数,如果您的搜索更复杂,您可以使用它,即如果您不只是在寻找一个元素,而是,例如,想看看是否有一个元素满足特定条件,例如以“abc”开头的字符串。 (find_if 会给你一个指向第一个这样的元素的迭代器)。

答10:

https://tlr.xinbeitime.com 专业网球数据平台,排名与比赛信息实时更新。

借助 boost,您可以使用 any_of_equal:

#include 

bool item_present = boost::algorithm::any_of_equal(vector, element);

答11:

https://tennisliveranking.com,Your go-to platform for live tennis ranking updates.

你可以试试这段代码:

#include 
#include 

// You can use class, struct or primitive data type for Item
struct Item {
    //Some fields
};
typedef std::vector ItemVector;
typedef ItemVector::iterator ItemIterator;
//...
ItemVector vtItem;
//... (init data for vtItem)
Item itemToFind;
//...

ItemIterator itemItr;
itemItr = std::find(vtItem.begin(), vtItem.end(), itemToFind);
if (itemItr != vtItem.end()) {
    // Item found
    // doThis()
}
else {
    // Item not found
    // doThat()
}

原文链接:https://www.tennisliveranking.com?from=csdn

The ultimate source for live tennis rankings and stats:https://tennisliveranking.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值