web-dev-qa-db-de.com

Wie finde ich heraus, ob ein Artikel in einem std :: vector vorhanden ist?

Ich möchte nur prüfen, ob ein Element im Vektor vorhanden ist oder nicht, damit ich mich mit jedem Fall befassen kann.

if ( item_present )
   do_this();
else
   do_that();
574
Joan Venge

Sie können std::find aus _<algorithm>_ verwenden:

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

Dies gibt einen Bool zurück (true falls vorhanden, false andernfalls). Mit deinem Beispiel:

_#include <algorithm>
#include <vector>

if ( std::find(vec.begin(), vec.end(), item) != vec.end() )
   do_this();
else
   do_that();
_
854
MSN

Wie bereits erwähnt, verwenden Sie die Funktionen STL find oder find_if . Wenn Sie jedoch in sehr großen Vektoren suchen und dies die Leistung beeinträchtigt, können Sie Ihren Vektor sortieren und dann binary_search , lower_bound verwenden , oder upper_bound Algorithmen.

106
Brian Neal

Verwenden Sie find aus dem Algorithmus-Header von stl.Ich habe seine Verwendung mit dem Typ int veranschaulicht. Sie können einen beliebigen Typ verwenden, solange Sie ihn auf Gleichheit prüfen können (Überladung ==, falls dies für Ihre benutzerdefinierte Klasse erforderlich ist).

#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;
}
46
m-sharp

Wenn Ihr Vektor nicht bestellt ist, verwenden Sie den von MSN vorgeschlagenen Ansatz:

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

Wenn Ihr Vektor bestellt ist, verwenden Sie die binary_search-Methode, die Brian Neal vorgeschlagen hat:

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

die binäre Suche liefert O (log n) Worst-Case-Performance, die weitaus effizienter ist als der erste Ansatz. Um die binäre Suche zu verwenden, können Sie qsort verwenden, um den Vektor zuerst zu sortieren, um sicherzustellen, dass er geordnet ist.

37
Bin Feng

Ich benutze so etwas ...

#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

... so ist es eigentlich klar und lesbar. (Natürlich können Sie die Vorlage an mehreren Stellen wiederverwenden.).

21
Andy Krouwel

Hier ist eine Funktion, die für jeden Container funktioniert:

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

Beachten Sie, dass Sie mit 1 Vorlagenparameter davonkommen können, da Sie den value_type aus dem Container extrahieren können. Sie benötigen typename, da Container::value_type ein abhängiger Name ist.

11

Denken Sie daran, dass es STL-Container gibt, die besser dafür geeignet sind, wenn Sie viele Suchvorgänge durchführen. Ich weiß nicht, was Ihre Anwendung ist, aber assoziative Container wie std :: map sind möglicherweise eine Überlegung wert.

std :: vector ist der Container der Wahl, es sei denn, Sie haben einen Grund für einen anderen, und Nachschlagen nach Wert kann ein solcher Grund sein.

10
David Thornley

In C++ 11 können Sie any_of verwenden. Wenn es zum Beispiel ein vector<string> v; ist, dann:

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

Verwenden Sie die Funktion STL find .

Beachten Sie, dass es auch eine find_if - Funktion gibt, die Sie verwenden können, wenn Ihre Suche komplexer ist, dh wenn Sie nicht nur nach einem Element suchen, sondern beispielsweise nachsehen möchten, ob es vorhanden ist ist ein Element, das eine bestimmte Bedingung erfüllt, z. B. eine Zeichenfolge, die mit "abc" beginnt. (find_if würde Ihnen einen Iterator geben, der auf das erste derartige Element verweist).

8
Frank

Mit boost können Sie any_of_equal verwenden:

_#include <boost/algorithm/cxx11/any_of.hpp>

bool item_present = boost::algorithm::any_of_equal(vector, element);
_
7
Mikhail

Sie können diesen Code ausprobieren:

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

Sie können die Funktion find verwenden, die sich im Namespace std befindet, dh std::find. Sie übergeben der Funktion std::find den Iterator begin und end des zu suchenden Vektors zusammen mit dem gesuchten Element und vergleichen den resultierenden Iterator mit dem Ende des Vektors, um festzustellen, ob sie übereinstimmen oder nicht.

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

Sie können diesen Iterator auch dereferenzieren und wie jeden anderen Iterator wie gewohnt verwenden.

3
TankorSmash

Sie können auch count verwenden. Es wird die Anzahl der in einem Vektor vorhandenen Elemente zurückgegeben.

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

Ein weiteres Beispiel mit C++ - Operatoren.

#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!");
  }
}

Wenn Sie eine Zeichenfolge in einem Vektor finden möchten:

    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));
2
Gank
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;
}
1
user3157855

(C++ 17 und höher):

kann auch std::search verwenden

Dies ist auch nützlich für die Suche nach Elementsequenzen.

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

Es gibt auch die Flexibilität, einige Suchalgorithmen zu übergeben. Hier beziehen.

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

0
Pavan Chandaka