Как узнать, присутствует ли элемент в std :: vector?

c++ vector std

841135 просмотра

18 ответа

Все, что я хочу сделать, это проверить, существует ли элемент в векторе или нет, чтобы я мог разобраться с каждым случаем.

if ( item_present )
   do_this();
else
   do_that();
Автор: Joan Venge Источник Размещён: 09.07.2019 01:22

Ответы (18)


847 плюса

Решение

Вы можете использовать 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();
Автор: MSN Размещён: 20.02.2009 10:00

105 плюса

Как уже говорили другие, используйте STL findили find_ifфункции. Но если вы ищете в очень больших векторов , и это влияет на производительность, вы можете сортировать вектор , а затем использовать binary_search, lower_boundили upper_boundалгоритмы.

Автор: Brian Neal Размещён: 20.02.2009 10:26

46 плюса

Используйте find из заголовка алгоритма stl. Я проиллюстрировал его использование с типом 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;
}
Автор: m-sharp Размещён: 20.02.2009 10:06

36 плюса

Если ваш вектор не упорядочен, используйте подход, предложенный MSN:

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

Если ваш вектор упорядочен, используйте метод binary_search, предложенный Брайаном Нилом:

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

Бинарный поиск дает O (log n) производительность в худшем случае, что намного эффективнее, чем первый подход. Чтобы использовать бинарный поиск, вы можете использовать qsort, чтобы сначала отсортировать вектор, чтобы гарантировать его упорядоченность.

Автор: Bin Feng Размещён: 23.11.2012 08:58

21 плюса

Я использую что-то вроде этого ...

#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

... так оно и есть на самом деле понятно и читаемо. (Очевидно, вы можете повторно использовать шаблон в нескольких местах).

Автор: Andy Krouwel Размещён: 04.09.2013 04:34

11 плюса

Вот функция, которая будет работать для любого контейнера:

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это зависимое имя .

Автор: Martin Broadhurst Размещён: 11.02.2016 09:38

10 плюса

Имейте в виду, что, если вы собираетесь выполнять много поисков, есть контейнеры STL, которые лучше подходят для этого. Я не знаю, какое у вас приложение, но стоит рассмотреть такие ассоциативные контейнеры, как std :: map.

std :: vector - контейнер выбора, если у вас нет причины для другого, и поиск по значению может быть такой причиной.

Автор: David Thornley Размещён: 20.02.2009 10:42

10 плюса

В C ++ 11 вы можете использовать any_of. Например, если это vector<string> v;тогда:

if (any_of(v.begin(), v.end(), bind(equal_to<string>(), item, _2)))
   do_this();
else
   do_that();
Автор: Deqing Размещён: 11.08.2015 04:15

8 плюса

Используйте функцию поиска STL .

Имейте в виду, что есть также функция find_if , которую вы можете использовать, если ваш поиск более сложный, т.е. если вы не просто ищете элемент, но, например, хотите посмотреть, есть ли элемент, который удовлетворяет определенному условие, например, строка, которая начинается с "abc". ( find_ifдаст вам итератор, который указывает на первый такой элемент).

Автор: Frank Размещён: 20.02.2009 10:18

7 плюса

С надстройкой вы можете использовать any_of_equal:

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

bool item_present = boost::algorithm::any_of_equal(vector, element);
Автор: Mikhail Размещён: 27.09.2016 04:02

5 плюса

Вы можете попробовать этот код:

#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()
}
Автор: TrungTN Размещён: 28.04.2012 03:29

3 плюса

Вы можете использовать findфункцию, найденную в stdпространстве имен, то есть std::find. Вы передаете std::findфункцию, beginи endитератор из вектора вы хотите найти, наряду с элементом вы ищете и сравнить получившийся итератор к концу вектора , чтобы увидеть , если они совпадают или нет.

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

Вы также можете разыменовать этот итератор и использовать его как обычно, как и любой другой итератор.

Автор: TankorSmash Размещён: 15.06.2014 12:36

3 плюса

Вы можете использовать счет тоже. Он вернет количество элементов, присутствующих в векторе.

int t=count(vec.begin(),vec.end(),item);
Автор: Aditya Размещён: 11.03.2015 10:00

2 плюса

Если вы хотите найти строку в векторе:

    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));
Автор: Gank Размещён: 31.05.2013 01:55

2 плюса

Еще один пример с использованием операторов 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!");
  }
}
Автор: Valdemar_Rudolfovich Размещён: 13.05.2016 08:57

1 плюс

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;
}
Автор: user3157855 Размещён: 26.01.2014 05:55

0 плюса

(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

Автор: Pavan Chandaka Размещён: 26.03.2019 07:23

-1 плюса

Используя Newton C ++, это проще, самодокументировано и быстрее, чем с std :: find, потому что возвращает 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();
Автор: Moises Rojo Размещён: 11.04.2018 12:10
Вопросы из категории :
32x32