Yang ingin saya lakukan adalah memeriksa apakah ada elemen dalam vektor atau tidak, jadi saya bisa menangani setiap kasus.
if ( item_present )
do_this();
else
do_that();
Yang ingin saya lakukan adalah memeriksa apakah ada elemen dalam vektor atau tidak, jadi saya bisa menangani setiap kasus.
if ( item_present )
do_this();
else
do_that();
Jawaban:
Anda dapat menggunakan std::find
dari <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()
Ini mengembalikan bool ( true
jika ada, false
jika tidak). Dengan contoh Anda:
#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
do_this();
else
do_that();
#include <algorithm>
atau Anda mungkin mendapatkan kesalahan yang sangat aneh seperti 'tidak dapat menemukan fungsi yang cocok di namespace std'
.find()
masih bukan fungsi anggota std::vector
, seperti yang Anda harapkan seharusnya? Saya ingin tahu apakah ini merupakan konsekuensi dari templating.
std::vector<>::find()
tidak akan memberikan keuntungan, juga tidak diperlukan, oleh karena itu, tidak, tidak boleh menjadi anggota Lihat juga en.wikipedia.org/wiki/Coupling_%28computer_programming%29
mvec.find(key) != mvec.cend()
lebih disukai daripada std::find(mvec.cbegin(), mvec.cend(), key) != mvec.cend()
.
Seperti yang orang lain katakan, gunakan STL find
atau find_if
fungsinya. Tetapi jika Anda sedang mencari dalam vektor yang sangat besar dan kinerja dampak ini, Anda mungkin ingin mengurutkan vektor Anda dan kemudian menggunakan binary_search
, lower_bound
atau upper_bound
algoritma.
Gunakan find dari header algoritma stl. Saya telah menggambarkan penggunaannya dengan tipe int. Anda dapat menggunakan jenis apa pun yang Anda suka selama Anda dapat membandingkan untuk kesetaraan (kelebihan == jika Anda perlu untuk kelas kustom Anda).
#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;
}
Jika vektor Anda tidak dipesan, gunakan pendekatan yang disarankan MSN:
if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
// Found the item
}
Jika vektor Anda dipesan, gunakan metode binary_search Brian Neal yang disarankan:
if(binary_search(vector.begin(), vector.end(), item)){
// Found the item
}
pencarian biner menghasilkan O (log n) kinerja kasus terburuk, yang jauh lebih efisien daripada pendekatan pertama. Untuk menggunakan pencarian biner, Anda dapat menggunakan qsort untuk mengurutkan vektor terlebih dahulu untuk memastikan itu dipesan.
std::sort
? qsort
sangat tidak efisien pada vektor .... lihat: stackoverflow.com/questions/12308243/…
Saya menggunakan sesuatu seperti ini ...
#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
... seperti itu sebenarnya jelas dan dapat dibaca. (Jelas Anda dapat menggunakan kembali templat di banyak tempat).
value_type
dari wadah untuk jenis elemen. Saya telah menambahkan jawaban seperti ini.
Di C ++ 11 Anda dapat menggunakan any_of
. Sebagai contoh jika itu adalah vector<string> v;
maka:
if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
do_this();
else
do_that();
Atau, gunakan lambda:
if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
do_this();
else
do_that();
bind1st
dan bind2nd
sudah usang sejak C ++ 11 dan sepenuhnya dihapus di C ++ 17. Gunakan bind
dengan placeholders
dan / atau lambda sebagai gantinya.
Inilah fungsi yang akan bekerja untuk semua Kontainer:
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();
}
Perhatikan bahwa Anda dapat lolos dengan 1 parameter templat karena Anda dapat mengekstraknya value_type
dari Container. Anda memerlukan typename
karena itu Container::value_type
adalah nama dependen .
Ingatlah bahwa, jika Anda akan melakukan banyak pencarian, ada wadah STL yang lebih baik untuk itu. Saya tidak tahu apa aplikasi Anda, tetapi wadah asosiatif seperti std :: map mungkin perlu dipertimbangkan.
std :: vector adalah wadah pilihan kecuali Anda memiliki alasan untuk yang lain, dan pencarian berdasarkan nilai dapat menjadi alasan seperti itu.
Gunakan fungsi temukan STL .
Ingatlah bahwa ada juga fungsi find_if , yang dapat Anda gunakan jika pencarian Anda lebih kompleks, yaitu jika Anda tidak hanya mencari elemen, tetapi, misalnya, ingin melihat apakah ada elemen yang memenuhi elemen tertentu kondisi, misalnya, string yang dimulai dengan "abc". ( find_if
akan memberi Anda iterator yang menunjuk ke elemen tersebut pertama).
Dengan peningkatan, Anda dapat menggunakan any_of_equal
:
#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);
Anda dapat mencoba kode ini:
#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()
}
Anda dapat menggunakan find
fungsi, yang ditemukan di std
namespace, yaitu std::find
. Anda melewatkan std::find
fungsi begin
dan end
iterator dari vektor yang ingin Anda cari, bersama dengan elemen yang Anda cari dan membandingkan iterator yang dihasilkan dengan ujung vektor untuk melihat apakah mereka cocok atau tidak.
std::find(vector.begin(), vector.end(), item) != vector.end()
Anda juga dapat melakukan dereferensi iterator dan menggunakannya seperti biasa, seperti iterator lainnya.
Anda dapat menggunakan hitungan juga. Ini akan mengembalikan jumlah item yang ada dalam vektor.
int t=count(vec.begin(),vec.end(),item);
find
lebih cepat daripada count
, karena tidak terus menghitung setelah pertandingan pertama.
Jika Anda ingin menemukan string dalam vektor:
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));
Sampel lain menggunakan operator 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 ke atas):
bisa digunakan std::search
juga
Ini juga berguna untuk mencari urutan elemen.
#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;
}
Juga ada fleksibilitas melewati beberapa algoritma pencarian. Rujuk ke sini.
Saya pribadi telah menggunakan template akhir-akhir ini untuk menangani beberapa jenis wadah sekaligus daripada hanya berurusan dengan vektor. Saya menemukan contoh serupa secara online (tidak ingat di mana) jadi kredit diberikan kepada siapa pun saya telah mencicilnya. Pola khusus ini tampaknya menangani array mentah juga.
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);
}
Menggunakan Newton C ++ lebih mudah, didokumentasikan sendiri dan lebih cepat daripada dengan std :: find karena mengembalikan bool secara langsung.
bool exists_linear( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
bool exists_binary( INPUT_ITERATOR first, INPUT_ITERATOR last, const T& value )
Saya pikir sudah jelas apa fungsinya.
include <newton/algorithm/algorithm.hpp>
if ( newton::exists_linear(first, last, value) )
do_this();
else
do_that();