Tüm yapmak istediğim, bir elemanın vektörde var olup olmadığını kontrol etmektir, böylece her durumla başa çıkabilirim.
if ( item_present )
do_this();
else
do_that();
Tüm yapmak istediğim, bir elemanın vektörde var olup olmadığını kontrol etmektir, böylece her durumla başa çıkabilirim.
if ( item_present )
do_this();
else
do_that();
Yanıtlar:
Sen kullanabilirsiniz std::find
den <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()
Bu bir bool döndürür ( true
varsa, false
aksi takdirde). Örneğinizle:
#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
do_this();
else
do_that();
#include <algorithm>
ya da 'ad alanı
.find()
hala bir üye işlevi olmadığı kimseyi rahatsız std::vector
etmedi mi? Bunun bir şekilde baştan çıkarmanın bir sonucu olup olmadığını merak ediyorum.
std::vector<>::find()
herhangi bir avantaj sağlamaz, ne de gerekli değildir, bu nedenle hayır, üye olmamalıdır. Ayrıca bkz. En.wikipedia.org/wiki/Coupling_%28computer_programming%29
mvec.find(key) != mvec.cend()
tercih edilir std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()
.
Diğerlerinin söylediği gibi, STL'yi kullanın find
veya find_if
işlevleri . Çok büyük vektörler arama ve bu etkiler performansı vardır Ama eğer vektör sıralamak istiyorum, sonra kullanabilir binary_search
, lower_bound
veya upper_bound
algoritmalar.
St türünün algoritma başlığından find komutunu kullanın. İnt türüyle kullanımını gösterdim. Eşitliği karşılaştırabildiğiniz sürece istediğiniz herhangi bir türü kullanabilirsiniz (özel sınıfınız için ihtiyacınız varsa aşırı yük ==).
#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;
}
Vektörünüz sipariş edilmemişse, MSN'in önerdiği yaklaşımı kullanın:
if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
// Found the item
}
Vektörünüz sipariş edildiyse, Brian Neal'ın önerdiği binary_search yöntemini kullanın:
if(binary_search(vector.begin(), vector.end(), item)){
// Found the item
}
ikili arama ilk yaklaşımdan çok daha verimli olan O (log n) en kötü durum performansını verir. İkili aramayı kullanmak için, vektörü sipariş edildiğini garanti etmek üzere önce sıralamak için qsort'u kullanabilirsiniz.
std::sort
? qsort
vektörler üzerinde çok verimsiz .... bakınız: stackoverflow.com/questions/12308243/…
Böyle bir şey kullanıyorum ...
#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
... bu şekilde aslında net ve okunabilir. (Açıkçası şablonu birden fazla yerde kullanabilirsiniz).
value_type
, öğe türü için kapsayıcıdan kullanırsanız 1 şablon bağımsız değişkeni ile kurtulabilirsiniz . Bunun gibi bir cevap ekledim.
C ++ 11'de kullanabilirsiniz any_of
. Örneğin, bir vector<string> v;
o zaman:
if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
do_this();
else
do_that();
Alternatif olarak, bir lambda kullanın:
if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
do_this();
else
do_that();
bind1st
ve bind2nd
edilmiştir , 11 C ++ yana kaldırıldı ve tamamen 17 C ++ uzaklaştırıldı. Kullanım bind
ile placeholders
yerine ve / veya lambdas.
İşte herhangi bir Kapsayıcı için çalışacak bir işlev:
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();
}
Kaptan ayıklayabileceğiniz için 1 şablon parametresiyle uzaklaşabileceğinizi unutmayın value_type
. İhtiyacınız typename
çünkü Container::value_type
bir olan bağımlı isim .
Çok fazla arama yapacaksanız, bunun için daha iyi olan STL kapları olduğunu unutmayın. Uygulamanızın ne olduğunu bilmiyorum, ancak std :: map gibi ilişkisel kaplar dikkate değer olabilir.
std :: vector, başka bir nedeniniz olmadığı sürece tercih edilen kaptır ve değere göre aramalar böyle bir neden olabilir.
STL bulmayı kullanın işlevini .
Aramanız daha karmaşıksa, yani yalnızca bir öğe aramıyorsanız, örneğin, belirli bir öğeyi karşılayan bir öğe olup olmadığını görmek istediğiniz bir find_if işlevi olduğunu unutmayın. koşul, örneğin, "abc" ile başlayan bir dize. ( find_if
bu tür ilk öğeye işaret eden bir yineleyici verir).
Boost ile şunları kullanabilirsiniz any_of_equal
:
#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);
Bu kodu deneyebilirsiniz:
#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()
}
Ad alanında find
bulunan işlevi kullanabilirsiniz std
, yani std::find
. Geçtin std::find
fonksiyonu begin
ve end
onlar maç ya da değil eğer elemanı ile birlikte aradığınız, arama ve karşılaştırmak istediğiniz vektör gelen yineleyici vektör sonuna kadar yineleyici çıkan görmek için.
std::find(vector.begin(), vector.end(), item) != vector.end()
Ayrıca yineleyiciyi kaldırabilir ve diğer yineleyiciler gibi normal olarak kullanabilirsiniz.
Sayıyı da kullanabilirsiniz. Bir vektörde bulunan öğe sayısını döndürür.
int t=count(vec.begin(),vec.end(),item);
find
daha hızlıdır count
, çünkü ilk maçtan sonra saymaya devam etmez.
Bir vektörde dize bulmak istiyorsanız:
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));
C ++ işleçlerini kullanan başka bir örnek.
#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 ve üstü):
kullanabilirsiniz std::search
da
Bu aynı zamanda elemanların sırasını aramak için de yararlıdır.
#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;
}
Ayrıca bazı arama algoritmalarını geçirme esnekliği vardır. Buraya bakın.
Kişisel olarak geç kalıpları sadece vektörlerle uğraşmak yerine aynı anda birden fazla kap türünü işlemek için kullandım. Benzer bir örnek çevrimiçi buldum (nerede hatırlayamıyorum) bu yüzden kredi bunu çaldı kim olursa olsun gider. Bu özel örüntü ham dizileri de ele almaktadır.
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 ++ kullanarak , doğrudan bir bool döndürmesi nedeniyle std :: find'a göre daha kolay, kendi kendine belgelenmiş ve daha hızlıdır.
bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
Bence fonksiyonların ne yaptığı açık.
include <newton/algorithm/algorithm.hpp>
if ( newton::exists_linear(first, last, value) )
do_this();
else
do_that();