我要做的只是检查向量中是否存在某个元素,因此我可以处理每种情况。
if ( item_present )
do_this();
else
do_that();
我要做的只是检查向量中是否存在某个元素,因此我可以处理每种情况。
if ( item_present )
do_this();
else
do_that();
Answers:
您可以使用std::find
从<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()
这将返回一个布尔值(true
如果存在,false
否则)。以您的示例为例:
#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
do_this();
else
do_that();
#include <algorithm>
否则您可能会遇到非常奇怪的错误,例如“在命名空间std中找不到匹配的函数”
.find()
它仍然不是的成员函数std::vector
,您是否希望它会成为困扰它的人呢?我想知道这是否是模板的结果。
std::vector<>::find()
不会提供任何优势,也不需要它,因此,不,它不应成为成员。另请参见en.wikipedia.org/wiki/Coupling_%28computer_programming%29
mvec.find(key) != mvec.cend()
优于std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()
。
正如其他人所说,使用STL find
或find_if
函数。但是,如果你在非常大的矢量搜索,这会影响性能,您可能要排序的载体,然后使用binary_search
,lower_bound
或upper_bound
算法。
使用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;
}
如果没有订购您的矢量,请使用建议的MSN方法:
if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
// Found the item
}
如果您的向量是有序的,请使用binary_search方法Brian Neal建议:
if(binary_search(vector.begin(), vector.end(), item)){
// Found the item
}
二进制搜索产生O(log n)最坏情况的性能,比第一种方法更有效。为了使用二进制搜索,您可以使用qsort首先对向量进行排序,以确保它是有序的。
我用这样的东西...
#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
从容器中使用元素类型,则可以使用1个模板参数。我添加了这样的答案。
在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
从Container中提取。您需要使用typename
因为Container::value_type
是从属名称。
请记住,如果您要进行大量查找,则可以使用STL容器来更好地进行查找。我不知道您的应用程序是什么,但是像std :: map这样的关联容器可能值得考虑。
除非您有其他原因,否则std :: vector是您选择的容器,按值查找可能就是这种原因。
使用boost可以使用any_of_equal
:
#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);
您可以尝试以下代码:
#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()
}
您可以使用find
在std
名称空间(即)中找到的函数std::find
。您可以将要搜索的向量中std::find
的begin
and end
迭代器与要查找的元素一起传递给函数,并将生成的迭代器与向量的末尾进行比较,以查看它们是否匹配。
std::find(vector.begin(), vector.end(), item) != vector.end()
您还可以取消引用该迭代器并像其他任何迭代器一样正常使用它。
使用C ++运算符的另一个示例。
#include <vector>
#include <algorithm>
#include <stdexcept>
template<typename T>
inline static bool operator ==(const std::vector<T>& v, const T& elem)
{
return (std::find(v.begin(), v.end(), elem) != v.end());
}
template<typename T>
inline static bool operator !=(const std::vector<T>& v, const T& elem)
{
return (std::find(v.begin(), v.end(), elem) == v.end());
}
enum CODEC_ID {
CODEC_ID_AAC,
CODEC_ID_AC3,
CODEC_ID_H262,
CODEC_ID_H263,
CODEC_ID_H264,
CODEC_ID_H265,
CODEC_ID_MAX
};
void main()
{
CODEC_ID codec = CODEC_ID_H264;
std::vector<CODEC_ID> codec_list;
codec_list.reserve(CODEC_ID_MAX);
codec_list.push_back(CODEC_ID_AAC);
codec_list.push_back(CODEC_ID_AC3);
codec_list.push_back(CODEC_ID_H262);
codec_list.push_back(CODEC_ID_H263);
codec_list.push_back(CODEC_ID_H264);
codec_list.push_back(CODEC_ID_H265);
if (codec_list != codec)
{
throw std::runtime_error("codec not found!");
}
if (codec_list == codec)
{
throw std::logic_error("codec has been found!");
}
}
(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;
}
还有一些传递搜索算法的灵活性。请参考这里。
我个人最近使用模板来一次处理多种类型的容器,而不仅仅是处理向量。我在网上找到了一个类似的示例(不记得在哪里),因此,无论我从谁那里窃取资金,都应归功于它。这种特殊的模式似乎也可以处理原始数组。
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 ++比使用std :: find更容易,具有自文档说明和更加快捷,因为它直接返回了布尔值。
bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
我认为功能很明显。
include <newton/algorithm/algorithm.hpp>
if ( newton::exists_linear(first, last, value) )
do_this();
else
do_that();