내가하고 싶은 것은 요소가 벡터에 존재하는지 여부를 확인하는 것이므로 각 경우를 처리 할 수 있습니다.
if ( item_present )
do_this();
else
do_that();
내가하고 싶은 것은 요소가 벡터에 존재하는지 여부를 확인하는 것이므로 각 경우를 처리 할 수 있습니다.
if ( item_present )
do_this();
else
do_that();
답변:
다음 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
}
벡터가 주문 된 경우 Brian Neal이 제안한 binary_search 메소드를 사용하십시오.
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();
또는 람다를 사용하십시오.
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();
}
value_type
컨테이너에서를 추출 할 수 있기 때문에 1 개의 템플릿 매개 변수를 사용하여 벗어날 수 있습니다 . 당신은 필요 typename
하기 때문에이 Container::value_type
A는 따라 이름 .
많은 조회를 수행하려는 경우 더 나은 STL 컨테이너가 있음을 명심하십시오. 귀하의 응용 프로그램이 무엇인지 모르지만 std :: map과 같은 연관 컨테이너를 고려해 볼 가치가 있습니다.
std :: vector는 다른 이유가없는 한 선택한 컨테이너이며 값별 조회가 그러한 이유 일 수 있습니다.
부스트를 사용하면 다음을 사용할 수 있습니다 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()
}
count도 사용할 수 있습니다. 벡터에있는 항목 수를 반환합니다.
int t=count(vec.begin(),vec.end(),item);
find
count
첫 번째 경기 후에 계산을 계속하지 않기 때문에 보다 빠릅니다 .
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!");
}
}
template <typename T> bool IsInVector(T what, std::vector<T> * vec)
{
if(std::find(vec->begin(),vec->end(),what)!=vec->end())
return true;
return false;
}
(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);
}
Newton C ++를 사용하면 직접 bool을 반환하기 때문에 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();