Hoe kom ik erachter of een item aanwezig is in een std::vector?

Het enige wat ik wil doen is controleren of een element in de vector bestaat of niet, zodat ik elk geval kan behandelen.

if ( item_present )
   do_this();
else
   do_that();

Antwoord 1, autoriteit 100%

U kunt std::findgebruiken van <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()

Dit geeft een bool terug (trueindien aanwezig, falseanders). Met jouw voorbeeld:

#include <algorithm>
#include <vector>
if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();

Antwoord 2, autoriteit 12%

Zoals anderen al hebben gezegd, gebruik de STL findof find_iffuncties. Maar als u in zeer grote vectoren zoekt en dit de prestaties beïnvloedt, wilt u misschien uw vector sorteren en vervolgens de binary_search, lower_bound, of upper_boundalgoritmen.


Antwoord 3, autoriteit 5%

Gebruik find uit de algoritme-header van stl. Ik heb het gebruik ervan geïllustreerd met het type int. Je kunt elk type gebruiken dat je wilt, zolang je kunt vergelijken voor gelijkheid (overload == als dat nodig is voor je aangepaste klas).

#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;
}

Antwoord 4, autoriteit 4%

Als uw vector niet is besteld, gebruikt u de door MSN voorgestelde aanpak:

if(std::find(vector.begin(), vector.end(), item)!=vector.end()){
      // Found the item
}

Als uw vector is besteld, gebruikt u de binary_search-methode die Brian Neal voorstelde:

if(binary_search(vector.begin(), vector.end(), item)){
     // Found the item
}

binair zoeken levert O(log n) slechtste prestaties op, wat veel efficiënter is dan de eerste benadering. Om binair zoeken te gebruiken, kunt u qsort gebruiken om de vector eerst te sorteren om te garanderen dat deze is geordend.


Antwoord 5, autoriteit 2%

Ik gebruik zoiets als dit…

#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

…op die manier is het echt duidelijk en leesbaar.
(Je kunt de sjabloon natuurlijk op meerdere plaatsen hergebruiken).


Antwoord 6, autoriteit 2%

In C++11 kun je any_ofgebruiken. Als het bijvoorbeeld een vector<string> v;dan:

if (any_of(v.begin(), v.end(), bind(equal_to<string>(), _1, item)))
   do_this();
else
   do_that();

U kunt ook een lambda gebruiken:

if (any_of(v.begin(), v.end(), [&](const std::string& elem) { return elem == item; }))
   do_this();
else
   do_that();

Antwoord 7

Hier is een functie die voor elke container werkt:

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();
}

Houd er rekening mee dat u weg kunt komen met 1 sjabloonparameter omdat u de value_typeuit de container kunt extraheren. U hebt de typenamenodig omdat Container::value_typeeen afhankelijke naam.


Antwoord 8

Houd er rekening mee dat, als je veel opzoekingen gaat doen, er STL-containers zijn die daar beter voor zijn. Ik weet niet wat je toepassing is, maar associatieve containers zoals std::map kunnen het overwegen waard zijn.

std::vector is de container naar keuze, tenzij je een reden hebt voor een andere, en opzoeken op waarde kan zo’n reden zijn.


Antwoord 9

Gebruik de STL vind-functie.

Houd er rekening mee dat er ook een find_if-functie is, die u kunt gebruik als uw zoekopdracht complexer is, dat wil zeggen als u niet alleen naar een element zoekt, maar bijvoorbeeld wilt zien of er een element is dat aan een bepaalde voorwaarde voldoet, bijvoorbeeld een string die begint met “abc”. (find_ifzou je een iterator geven die naar het eerste dergelijke element verwijst).


Antwoord 10

Met boost kun je any_of_equal:

#include <boost/algorithm/cxx11/any_of.hpp>
bool item_present = boost::algorithm::any_of_equal(vector, element);

Antwoord 11

U kunt deze code proberen:

#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()
}

Antwoord 12

U kunt de findfunctie, gevonden In de stdNAMESPACE, IE std::find. U passeert de std::findFunctie De beginen enditerator uit de vector die u wilt zoeken, samen met het element dat u kijkt Voor en vergelijk de resulterende iterator aan het einde van de vector om te zien of ze overeenkomen of niet.

std::find(vector.begin(), vector.end(), item) != vector.end()

U kunt ook Derference Die iterator en het normaal gebruiken, zoals elke andere iterator.


Antwoord 13

U kunt ook telling gebruiken.
Het zal het aantal items in een vector retourneren.

int t=count(vec.begin(),vec.end(),item);

Antwoord 14

Als u een touw in een vector wilt vinden:

   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));

Antwoord 15

(C++17 en hoger):

kan std::searchook gebruiken

Dit is ook handig om opeenvolging van elementen te zoeken.

#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;
}

Er is ook flexibiliteit om enkele zoekalgoritmen door te geven. Zie hier.

https://en.cppreference.com/w/cpp/algorithm/search


Antwoord 16

template <typename T> bool IsInVector(const T & what, const std::vector<T> & vec)
{
    return std::find(vec.begin(),vec.end(),what)!=vec.end();
}

Antwoord 17

Ik heb de laatste tijd persoonlijk sjablonen gebruikt om meerdere soorten containers tegelijk te verwerken in plaats van alleen met vectoren om te gaan. Ik vond een soortgelijk voorbeeld online (kan me niet herinneren waar) dus de eer gaat naar degene van wie ik dit heb gestolen. Dit specifieke patroon lijkt ook om te gaan met onbewerkte arrays.

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);
}

Other episodes