如何找出一个项目是否存在于d::向量中?

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

if ( item_present )
do_this();
else
do_that();
1306586 次浏览

您可以从<algorithm>使用std::find

#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();

我已经说明了它与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;
}

使用STL找到函数。

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

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

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

STd::向量是选择的容器,除非您有另一个原因,并且按值查找可能是这样的原因。

您可以尝试此代码:

#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()
}

如果您的向量没有排序,请使用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)的最坏情况性能,这比第一种方法效率高得多。为了使用二分搜索,你可以使用qsor首先对向量进行排序,以保证它是有序的。

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

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));

我用这样的东西…

#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

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

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

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

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

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

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

int t=count(vec.begin(),vec.end(),item);

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

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();

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

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依赖名

你可以使用any_of_equal

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


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

(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

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

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);
}

从C++20,使用范围(#include <ranges>

    //SAMPLE DATA
std::vector<int> vecOfElements = { 2,4,6,8 };


//DO SOMETHING IF 8 IN VECTOR
if (std::ranges::find(vecOfElements, 8) != vecOfElements.end())
{
std::cout << "DO SOMETHING" << std::endl;
}