كيفية معرفة ما إذا كان عنصر موجود في STD :: Vector؟

StackOverflow https://stackoverflow.com/questions/571394

  •  05-09-2019
  •  | 
  •  

سؤال

كل ما أريد القيام به هو التحقق مما إذا كان العنصر موجود في المتجه أم لا، حتى أتمكن من التعامل مع كل حالة.

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

هذا إرجاع bool (true إذا كان موجودا، false غير ذلك). مع مثالك:

#include <algorithm>
#include <vector>

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

نصائح أخرى

كما قال آخرون، استخدم STL find أو find_if المهام. ولكن إذا كنت تبحث في ناقلات كبيرة جدا وهذا يؤثر الأداء، فقد ترغب في فرز متجهك ثم استخدام binary_search, lower_bound, ، أو upper_bound الخوارزميات.

استخدم البحث عن رأس الخوارزمية من STL.I've يوضح استخدامه باستخدام نوع 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
}

إذا تم طلب ناقلك، استخدم طريقة Binary_Search Brian Neal المقترحة:

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

نتائج البحث الثنائية عائدات O (سجل ن) أسوأ الأداء، وهو وسيلة أكثر كفاءة من النهج الأول. من أجل استخدام البحث الثنائي، يمكنك استخدام 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

... وبهذه الطريقة أمر واضح وقابل للقراءة بالفعل. (من الواضح أنه يمكنك إعادة استخدام القالب في أماكن متعددة).

إليك وظيفة تعمل مع أي حاوية:

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

لاحظ أنه يمكنك الابتعاد مع 1 معلمة قالب لأنه يمكنك استخراج value_type من الحاوية. تحتاج إلى typename لأن Container::value_type هو الاسم المعتمد.

ضع في اعتبارك أنه إذا كنت ستقوم بعمل الكثير من عمليات البحث، فهناك حاويات STL هي أفضل لذلك. لا أعرف ما هو التطبيق الخاص بك، ولكن حاويات النظامية مثل STD :: خريطة قد تستحق النظر في ذلك.

STD :: Vector هو حاوية الاختيار إلا إذا كان لديك سبب لآخر، والبحث عن طريق القيمة يمكن أن يكون مثل هذا السبب.

في 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();

استخدام STL. تجد وظيفة.

ضع في اعتبارك أن هناك أيضا find_if. وظيفة، والتي يمكنك استخدامها إذا كان البحث الخاص بك أكثر تعقيدا، أي إذا كنت لا تبحث فقط عن عنصر، ولكن، على سبيل المثال، نريد معرفة ما إذا كان هناك عنصر يفي بحالة معينة، على سبيل المثال، سلسلة تبدأ مع "ABC". فيfind_if من شأنه أن يمنحك مزاذا لمقاابط يشير إلى أول عنصر من هذا القبيل).

مع زيادة يمكنك استخدام 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()
}

يمكنك استعمال ال find وظيفة، وجدت في std مساحة الاسم، أي std::find. وبعد أنت تمر std::find وظيفة begin و end إن جهاز التنفيذ من المتجه الذي تريد البحث فيه، جنبا إلى جنب مع العنصر الذي تبحث عنه ومقارنة الماسيرات الناتجة عن نهاية المتجه لمعرفة ما إذا كانت تتطابق أم لا.

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

أنت أيضا قادرة على إلغاء هذا المزارع واستخدامها كالمعتاد، مثل أي جهاز كمتقل آخر.

يمكنك استخدام العدد أيضا. سيعود عدد العناصر الموجودة في متجه.

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

إذا كنت تريد العثور على سلسلة في متجه:

    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 ++.

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

هناك أيضا مرونة في اجتياز بعض خوارزميات البحث. الرجوع هنا.

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

استخدام نيوتن C ++. من الأسهل، موثقة ذاتيا وأسرع من STD :: ابحث بسبب إرجاع Bool مباشرة.

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();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top