726

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

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

17 回答 17

1075

您可以使用std::find来自<algorithm>

#include <algorithm>
#include <vector>
vector<int> 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 <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();
于 2009-02-20T22:00:50.537 回答
123

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

于 2009-02-20T22:26:14.953 回答
52

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

#include <algorithm>
#include <vector>

using namespace std;
int main()
{   
    typedef vector<int> 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;
}
于 2009-02-20T22:06:50.880 回答
51

如果您的向量未排序,请使用 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 对向量进行排序,以保证它是有序的。

于 2012-11-23T08:58:39.277 回答
23

我用这样的东西......

#include <algorithm>


template <typename T> 
const bool Contains( std::vector<T>& 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

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

于 2013-09-04T16:34:07.027 回答
22

在 C++11 中,您可以使用any_of. 例如,如果它是一个vector<string> v;then:

if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _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();
于 2015-08-11T04:15:57.720 回答
13

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

template <class Container> 
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从属名称

于 2016-02-11T21:38:51.830 回答
10

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

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

于 2009-02-20T22:42:36.647 回答
8

使用 STL查找功能。

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

于 2009-02-20T22:18:34.877 回答
7

使用 boost,您可以使用any_of_equal

#include <boost/algorithm/cxx11/any_of.hpp>

bool item_present = boost::algorithm::any_of_equal(vector, element);
于 2016-09-27T16:02:37.367 回答
5

你可以试试这段代码:

#include <algorithm>
#include <vector>

// You can use class, struct or primitive data type for Item
struct Item {
    //Some fields
};
typedef std::vector<Item> 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()
}
于 2012-04-28T15:29:48.190 回答
4

您可以使用命名空间find中的函数std,即std::find. 您从要搜索的向量中传递std::find函数 thebeginend迭代器,以及要查找的元素,并将生成的迭代器与向量的末尾进行比较,以查看它们是否匹配。

std::find(vector.begin(), vector.end(), item) != vector.end()

您还可以取消引用该迭代器并像任何其他迭代器一样正常使用它。

于 2014-06-15T00:36:20.523 回答
3
template <typename T> bool IsInVector(const T & what, const std::vector<T> & vec)
{
    return std::find(vec.begin(),vec.end(),what)!=vec.end();
}
于 2014-01-26T17:55:40.613 回答
3

您也可以使用计数。它将返回向量中存在的项目数。

int t=count(vec.begin(),vec.end(),item);
于 2015-03-11T10:00:12.313 回答
2

我个人最近使用模板来一次处理多种类型的容器,而不是只处理向量。我在网上找到了一个类似的例子(不记得在哪里)所以归功于我从谁那里偷来的。这种特殊的模式似乎也可以处理原始数组。

template <typename Container, typename T = typename std::decay<decltype(*std::begin(std::declval<Container>()))>::type>
bool contains(Container && c, T v)
{
    return std::find(std::begin(c), std::end(c), v) != std::end(c);
}
于 2019-10-28T15:23:52.253 回答
1

如果你想在向量中找到一个字符串:

    struct isEqual
{
    isEqual(const std::string& s): m_s(s)
    {}

    bool operator()(OIDV* l)
    {
        return l->oid == m_s;
    }

    std::string m_s;
};
struct OIDV
{
    string oid;
//else
};
VecOidv::iterator itFind=find_if(vecOidv.begin(),vecOidv.end(),isEqual(szTmp));
于 2013-05-31T13:55:53.397 回答
1

(C++17 及以上):

std::search也可以用

这对于搜索元素序列也很有用。

#include <algorithm>
#include <iostream>
#include <vector>

template <typename Container>
bool search_vector(const Container& vec, const Container& searchvec)
{
    return std::search(vec.begin(), vec.end(), searchvec.begin(), searchvec.end()) != vec.end();
}

int main()
{
     std::vector<int> v = {2,4,6,8};

     //THIS WORKS. SEARCHING ONLY ONE ELEMENT.
     std::vector<int> searchVector1 = {2};
     if(search_vector(v,searchVector1))
         std::cout<<"searchVector1 found"<<std::endl;
     else
         std::cout<<"searchVector1 not found"<<std::endl;

     //THIS WORKS, AS THE ELEMENTS ARE SEQUENTIAL.
     std::vector<int> searchVector2 = {6,8};
     if(search_vector(v,searchVector2))
         std::cout<<"searchVector2 found"<<std::endl;
     else
         std::cout<<"searchVector2 not found"<<std::endl;

     //THIS WILL NOT WORK, AS THE ELEMENTS ARE NOT SEQUENTIAL.
     std::vector<int> searchVector3 = {8,6};
     if(search_vector(v,searchVector3))
         std::cout<<"searchVector3 found"<<std::endl;
     else
         std::cout<<"searchVector3 not found"<<std::endl;
}

还有传递一些搜索算法的灵活性。参考这里。

https://en.cppreference.com/w/cpp/algorithm/search

于 2019-03-26T19:23:26.373 回答