提问人:Joan Venge 提问时间:2/21/2009 最后编辑:AntonioJoan Venge 更新时间:9/30/2023 访问量:1455007
如何确定某个项目是否存在于 std::vector 中?
How to find out if an item is present in a std::vector?
答:
你可以从以下位置使用 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();
评论
#include <algorithm>
.find()
std::vector
std::vector<>::find()
mvec.find(key) != mvec.cend()
std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()
使用 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;
}
评论
使用 STL 查找功能。
请记住,还有一个find_if函数,如果您的搜索更复杂,即如果您不只是在寻找一个元素,而是想要查看是否存在满足特定条件的元素,例如,以“abc”开头的字符串,则可以使用该函数。( 会给你一个指向第一个此类元素的迭代器)。find_if
正如其他人所说,使用 STL 查找
或find_if
函数。但是,如果您在非常大的向量中进行搜索,这会影响性能,则可能需要对向量进行排序,然后使用 binary_search
、lower_bound
或 upper_bound
算法。
评论
请记住,如果您要进行大量查找,那么 STL 容器会更适合此。我不知道您的应用程序是什么,但像 std::map 这样的关联容器可能值得考虑。
std::vector 是首选的容器,除非您有另一个原因,而按值查找可能就是这样的原因。
评论
您可以尝试以下代码:
#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) 最坏情况的性能,这比第一种方法更有效。为了使用二进制搜索,您可以先使用 qsort 对向量进行排序,以确保它是有序的。
评论
std::sort
qsort
如果要在向量中查找字符串:
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));
评论
std::find
在这种情况下就好了,不需要谓词对象。
我用这样的东西......
#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
...因为这样一来,它实际上清晰易读。 (显然,您可以在多个位置重复使用模板)。
评论
value_type
if true return true else return false
return std::find(Vec.begin(), Vec.end(), Element) != Vec.end();
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()
find()
stdx::find()
您可以使用在命名空间中找到的 find
函数,即 .从要搜索的向量中传递函数 和 迭代器,以及要查找的元素,并将生成的迭代器与向量的末尾进行比较,以查看它们是否匹配。std
std::find
std::find
begin
end
std::find(vector.begin(), vector.end(), item) != vector.end()
您还可以取消引用该迭代器并像往常一样使用它,就像任何其他迭代器一样。
您也可以使用 count。 它将返回向量中存在的项数。
int t=count(vec.begin(),vec.end(),item);
评论
find
比 快,因为它不会在第一场比赛后继续计数。count
在 C++11 中,您可以使用 .例如,如果它是 then: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();
评论
std::any_of()
std::find()
std::find()
std::any_of
下面是一个适用于任何容器的函数:
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 个模板参数,因为您可以从容器中提取 。您需要 because 是一个依赖名称。value_type
typename
Container::value_type
评论
ranges
Range
Container
使用 boost,您可以使用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);
}
评论
template <typename Container> struct value_type { ... etc. ... }
从 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;
}
另一种方法是使用 std::count
。
示例代码:
#include <algorithm>
#include <vector>
void run_vector_contains_example() {
std::vector<int> vec = {1, 2, 3, 4, 5};
int item_to_find = 3;
int count = std::count(vec.begin(), vec.end(), item_to_find);
if (count > 0) {
// item found in vector
} else {
// item not found in vector
}
}
诚然,这种方法可能比处理大型向量时慢。std::find
评论
在 C++23 中,我们终于有了最明显的解决方案:
if (std::ranges::contains(vec, item))
do_this();
else
do_that();
评论
std::vector