В этом посте будет обсуждаться, как проверить, присутствует ли элемент в векторе на C++.
1. Использование std::find
Эффективным решением является использование стандартного алгоритма std::find
чтобы найти значение в указанном диапазоне. Он определен в <algorithm>
заголовок. Преимущество использования std::find
заключается в том, что он прекращает поиск, как только найдено совпадение.
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; bool found = std::find(vec.begin(), vec.end(), target) != vec.end(); std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать Выполнить код
2. Использование std::find_if
The std::find_if
Алгоритм возвращает итератор к первому элементу в указанном диапазоне, для которого предикат возвращает значение true. Чтобы проверить, присутствует ли элемент в векторе, предикат должен сопоставить текущий элемент с целевым, как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; auto it = std::find_if(vec.begin(), vec.end(), [&](const int& i) { return i == target; }); bool found = it != vec.end(); std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать Выполнить код
3. Использование std::binary_search
Если vector отсортирован, используйте std::binary_search
алгоритм, который возвращает логическое значение в зависимости от того, найден ли элемент в указанном диапазоне или нет. Преимущество использования std::binary_search
в том, что он работает всего за O(log(n)) время.
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec { —6, —3, 1, 2, 7, 8 }; int target = 7; bool found = std::binary_search(vec.begin(), vec.end(), target); std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать Выполнить код
4. Использование std::any_of
функция
The std::any_of
Алгоритм возвращает true, если предикат возвращает true для любого из элементов в указанном диапазоне. Чтобы проверить, присутствует ли элемент в векторе, предикат должен найти совпадение с целью. Например,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; bool found = std::any_of(vec.begin(), vec.end(), [&](int &i) { return i == target; }); std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать Выполнить код
5. Использование std::count
Другой вариант — использовать стандартный алгоритм std::count
, который возвращает количество элементов, соответствующих указанному значению в указанном диапазоне. std::count
работает медленнее, чем std::find
функция, так как она проходит весь список, тогда как std::find
останавливается на первом совпадении.
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; bool found = std::count(vec.begin(), vec.end(), target) > 0; std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать Выполнить код
6. Использование библиотеки Boost
Если вы используете библиотеку Boost в своем проекте, вы можете использовать boost::algorithm::any_of_equal
функция из заголовочного файла <boost/algorithm/cxx11/any_of.hpp>
. Он возвращается true
если любой из элементов в диапазоне равен указанному значению. Это показано ниже:
#include <iostream> #include <vector> #include <boost/algorithm/cxx11/any_of.hpp> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; bool found = boost::algorithm::any_of_equal(vec, target); std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать код
7. Использование диапазонов C++20
C++ 20 ranges library предоставляет компоненты для работы с диапазонами элементов, включая различные адаптеры представления. std::views::filter
создает представление по диапазону элементов, соответствующих предикату.
В следующем примере кода показан вызов этой функции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <ranges> #include <vector> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; auto match = vec | std::views::filter([&target](auto &v) { return v == target; }); std::vector<int> matches {match.begin(), match.end()}; bool found = matches.size() > 0; std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать код
До C++20 вам нужно было сделать что-то вроде ниже, чтобы создать контейнер с совпадениями:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec { 6, 3, 8, —9, 1, —2, 8 }; int target = —9; std::vector<int> matches; std::copy_if(vec.begin(), vec.end(), std::back_inserter(matches), [&](int v) { return v == target; }); bool found = matches.size() > 0; std::cout << std::boolalpha << found << std::endl; // true return 0; } |
Скачать Выполнить код
Это все о проверке наличия элемента в векторе в C++.
Something like this, I think. find_if_counted.hpp
:
#ifndef FIND_IF_COUNTED_HPP
#define FIND_IF_COUNTED_HPP
#include <algorithm>
namespace find_if_counted_impl
{
template <typename Func>
struct func_counter
{
explicit func_counter(Func& func, unsigned &count) :
_func(func),
_count(count)
{
}
template <typename T>
bool operator()(const T& t)
{
++_count;
return _func(t);
}
private:
Func& _func;
unsigned& _count;
};
}
// generic find_if_counted,
// returns the index of the found element, otherwise returns find_if_not_found
const size_t find_if_not_found = static_cast<size_t>(-1);
template <typename InputIterator, typename Func>
size_t find_if_counted(InputIterator start, InputIterator finish, Func func)
{
unsigned count = 0;
find_if_counted_impl::func_counter<Func> f(func, count);
InputIterator result = find_if(start, finish, f);
if (result == finish)
{
return find_if_not_found;
}
else
{
return count - 1;
}
}
#endif
Example:
#include "find_if_counted.hpp"
#include <cstdlib>
#include <iostream>
#include <vector>
typedef std::vector<int> container;
int rand_number(void)
{
return rand() % 20;
}
bool is_even(int i)
{
return i % 2 == 0;
}
int main(void)
{
container vec1(10);
container vec2(10);
std::generate(vec1.begin(), vec1.end(), rand_number);
std::generate(vec2.begin(), vec2.end(), rand_number);
unsigned index = find_if_counted(vec1.begin(), vec1.end(), is_even);
if (index == find_if_not_found)
{
std::cout << "vec1 has no even numbers." << std::endl;
}
else
{
std::cout << "vec1 had an even number at index: " << index <<
" vec2's corresponding number is: " << vec2[index] << std::endl;
}
}
Though I feel like I’m doing something silly… :X Any corrections are welcome, of course.
На чтение 9 мин Просмотров 13.7к. Опубликовано 15.09.2021
Вектор C ++ не имеет функции-члена поиска. Однако в библиотеке алгоритмов есть функции find () разных типов, которые можно использовать для поиска чего-либо в векторе C ++. В библиотеке алгоритмов есть четыре группы функций find (), которые можно классифицировать как «Найти», «Найти конец», «Найти сначала» и «Найти по соседству».
Чтобы использовать библиотеки векторов и алгоритмов, программа на C ++ должна начинаться с:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
В этом руководстве приведены основы поиска значения в векторе C ++. Весь код в этом руководстве находится в функции main (), если не указано иное. Если вектор состоит из строк, используйте строковый класс; и не используйте «const char *». В этом случае также должен быть включен строковый класс, например:
Содержание
- Find
- Чувствительность к регистру
- Range Within Limits
- More Than One Occurrence
- Finding Integer
- Predicate
- Заключение
Find
InputIterator find (сначала InputIterator, последним InputIterator, const T & value);
Следующий код использует эту функцию, чтобы узнать, входит ли цветок «Василек» в векторный список цветов:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vectorvtr = {«Dog Rose», «Honeysuckle», «Enchanter’s nightshade», «Columbine», «Kingcup», «Cornflower», «Water avens», «Forget-me-not»};vector::iterator it = find(vtr.begin(), vtr.end(), «Cornflower»);
if (it == vtr.end())
cout<< «Flower was not found!» <<endl;
else
cout<< «Flower found at index: « << it — vtr.begin() <<endl;return 0;
}
Результат:
Целый список вектора был целью поиска. Судя по синтаксису функции find (), «first» — это vtr.begin () в коде, а «last» — это vtr.end () в коде. Значение, которое нужно искать в синтаксисе функции find (), обозначенное как const-T & -value, в коде имеет значение «Василек».
Функция find () просматривает список векторов с самого начала. Если он не видит искомого значения, он достигнет конца вектора. Конец вектора — это официально vtr.end (), который находится сразу за последним элементом. Если он не видит искомого значения, он вернет итератор, указывающий на vtr.end ().
Значение, которое он ищет, может находиться в разных местах одного и того же вектора. Когда он видит первое из искомых значений, он останавливается на нем и возвращает итератор, указывающий на это значение.
Каждое значение в векторе имеет индекс. Первое значение имеет индекс 0, соответствующий vtr.begin (). Второе значение имеет индекс 1, соответствующий vtr.begin () + 1. Третье значение имеет индекс 2, соответствующий vtr.begin () + 2. Четвертое значение имеет индекс 3, соответствующий vtr.begin () + 3. ; и так далее. Итак, индекс первого найденного значения определяется как:
Чувствительность к регистру
Поиск в векторе чувствителен к регистру. Если бы значение, которое нужно было найти, было «CORNFLOWER» для указанной выше программы, оно не было бы найдено и была бы возвращена vtr.end ().
Range Within Limits
Диапазон не обязательно должен составлять весь вектор. Для приведенной выше программы диапазон мог быть от индекса 1 до индекса 4. То есть от «vtr.begin () + 1» до «vtr.end () — 4». «Vtr.end () — 4» получается вычитанием из обратного с учетом того, что vtr.end () находится сразу за самым последним элементом.
Когда весь список векторов является диапазоном, проверка того, является ли итератор возврата vtr.end (), показывает, было ли значение найдено или нет. Если итератором возврата является vtr.end (), это означает, что значение не было найдено. Теперь, когда диапазон меньше, если итератор возврата является последним элементом выбранного диапазона, это означает, что значение либо не было найдено, либо это последнее значение диапазона.
Примечание. Поиск останавливается на последнем элементе выбранного (меньшего) диапазона, если значение не было найдено в этом диапазоне или если найденное значение является последним элементом выбранного диапазона. Если найденное значение было этим последним элементом, будет возвращен итератор, указывающий на него. Если значение было найдено раньше, поиск остановится на этом элементе перед последним элементом выбранного диапазона. Итератор этого элемента будет возвращен.
Следующий код иллюстрирует эту схему:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vectorvtr = {«Dog Rose», «Honeysuckle», «Enchanter’s nightshade», «Columbine», «Kingcup», «Cornflower», «Water avens», «Forget-me-not»};vector::iterator it = find(vtr.begin() + 1, vtr.end() — 4, «Cornflower»);
if (it == vtr.end())
cout<< «Flower was not found!» <<endl;
else if (it — vtr.begin() == 4) { //last element in chosen range
if (*it == string(«Cornflower»))
cout<< «Flower found at index: « << it — vtr.begin() <<endl;
else
cout<< «Flower was not found in range!» <<endl;
}
else {
cout<< «Flower found at index: « << it — vtr.begin() <<endl;
}return 0;
}
Результат:
Flower was not found in range!
Теперь «Василек» имеет индекс 5, а «Kingcup» — индекс 4. Последний элемент в небольшом диапазоне, выбранном для поиска, — «Kingcup». Итак, соответствующее условие теста — «it — vtr.begin () == 4». Обратите внимание, что выражения «vtr.end () — 4» и «it — vtr.begin () == 4», каждое из которых имеет 4, являются просто совпадением.
Чтобы «Василек» был в малом диапазоне поиска, соответствующее условие проверки должно быть «it — vtr.begin () == 5». Следующий код иллюстрирует это:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vectorvtr = {«Dog Rose», «Honeysuckle», «Enchanter’s nightshade», «Columbine», «Kingcup», «Cornflower», «Water avens», «Forget-me-not»};vector::iterator it = find(vtr.begin() + 1, vtr.end() — 3, «Cornflower»);
if (it == vtr.end())
cout<< «Flower was not found!» <<endl;
else if (it — vtr.begin() == 5) {
if (*it == string(«Cornflower»))
cout<< «Flower found at index: « << it — vtr.begin() <<endl;
else
cout<< «Flower was not found in range!» <<endl;
}
else {
cout<< «Flower found at index: « << it — vtr.begin() <<endl;
}return 0;
}
Результат:
More Than One Occurrence
В следующей программе «Василек» встречается более чем в одном месте. Чтобы найти все индексы вхождений, используйте цикл while для продолжения поиска после предыдущего вхождения до конца (vtr.end ()) вектора. Программа:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vectorvtr = {«Dog Rose», «Cornflower», «Enchanter’s nightshade», «Columbine», «Kingcup», «Cornflower», «Water avens», «Cornflower»};vector::iterator it = find(vtr.begin(), vtr.end(), «Cornflower»);
while (it != vtr.end()) {
if (*it == string(«Cornflower»))
cout<< «Flower found at index: « << it — vtr.begin() <<endl;
it++;
}return 0;
}
Результат:
Flower found at index: 1
Flower found at index: 5
Flower found at index: 7
Finding Integer
Вектор может состоять из целых чисел. Первое целочисленное значение можно найти с помощью функции find () (из библиотеки алгоритмов). Следующая программа иллюстрирует это:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vectorvtr = {1, 2, 3, 1, 2, 3, 1, 2, 3};vector::iterator it = find(vtr.begin(), vtr.end(), 3);
if (it == vtr.end())
cout<< «Number was not found!» <<endl;
else
cout<< «Number found at index: « << it — vtr.begin() <<endl;return 0;
}
Результат:
Number found at index: 2
for the first occurrence of the value, 3.
Predicate
InputIterator find_if (сначала InputIterator, затем — InputIterator, предикат предиката);
Здесь используется функция find_if (), а не просто find (). Pred — это имя функции, которая дает критерии поиска. Этот третий аргумент принимает только имя функции, без аргументов и без скобок. Если функция-предикат принимает аргумент, тогда в определении функции указываются параметры для аргументов. Следующая программа иллюстрирует это, ища первое четное число в списке векторов:
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
bool fn(int n) {
if ((n % 2) == 0)
return true;
else
return false;
}int main()
{
vectorvtr = {1, 3, 5, 7, 8, 9, 10, 11, 12};vector::iterator it = find_if(vtr.begin(), vtr.end(), fn);
if (it == vtr.end())
cout<< «Number was not found!» <<endl;
else
cout<< «Number found at index: « << it — vtr.begin() <<endl;return 0;
}
Результат:
Обратите внимание, что был выполнен поиск по всему вектору с диапазоном «vtr.begin (), vtr.end ()».
Имя функции-предиката здесь — fn. Требуется один аргумент — целое число. Когда функция find_if () начинает сканирование вектора с первого элемента, она вызывает функцию предиката с каждым числом в векторе в качестве аргумента. Сканирование останавливается, когда он достигает первого элемента в векторе, для которого предикат возвращает истину.
Заключение
Функция find () в библиотеке алгоритмов существует в четырех категориях: «Найти», «Найти конец», «Найти сначала» и «Найти по соседству». Только категория «Найти» была объяснена выше, и в значительной степени. Приведенное выше объяснение является основой для всех функций find () в библиотеке алгоритмов. Функции Find () имеют дело с итераторами напрямую и косвенно с индексами. Программист должен знать, как преобразовать итератор в индексную и общую арифметику итератора, как показано выше.
Indian Technical Authorship Contest starts on 1st July 2023. Stay tuned.
In this article, we have explained Different Ways to find element in Vector in C++ STL which includes using std::find(), std::find_if, std::distance, std::count and Linear Search.
Table of contents:
- Introduction to Vector in C++ and STL
- How do we find an element using STL?
- Approach 1: Return index of the element using std::find()
- Use std::find_if() with std::distance()
- Use std::count()
- Linear search
Let us get started with Different Ways to find element in Vector in C++ STL.
Introduction to Vector in C++ and STL
A vector in C++ is just like an array in any other language but it is dynamic which means its size is not static. Why vectors? Well, arrays in C++ are static and once declared we cannot change their sizes which is not favourable when we need to store a data set whose size we are unsure of.
Unlike arrays we can determine the size of a vector at runtime and that is what makes vectors a perfect choice for these types of scenarios, they are dynamically allocated which means they can be resized.
The STL stands for Standard Template Library. Basically STL contains some generic functions that we shall need for this tutorial.
How do we find an element using STL?
There are three ways in which we can approach this problem:
Approach 1: By returning the index position of the element in the vector. Here we use std::find() and std::find_if()
Approach 2: By returning a boolean value, true if element is in the vector and false otherwise. Here we use std::count().
Approach 3: No STL here, we use linear search where by we go all through the vector elements making comparisons between the elements and key k.
Approach 1: Return index of the element using std::find()
std::find() searches for an element equal to the value that is passed as a parameter and returns an iterator pointing to that element in the vector.
In our case it will look like the following:
it = std::find(arr.begin(), arr.end(), k)
The parameter passed here is key k, the function call will return an iterator pointing to key k in the vector.
#include<bits/stdc++.h>
int searchResult(std::vector<int> arr, int k){
std::vector<int>::iterator it;
it = std::find(arr.begin(), arr.end(), k);
if(it != arr.end())
return (it - arr.begin());
else
return -1;
}
int main(){
std::vector<int> arr = {1, 2, 3, 4, 5, 6};
int k = 4;
std::cout << searchResult(arr, k) << std::endl;
return 0;
}
Code Explanation
This piece of code returns the index for the element we are trying to find and -1 if the element is not present in the vector.
Line 1: The header file declared includes every standard library in c++ and it contains the find function we need.
Line 2: We declare a function that takes a vector and key to be searched as parameters.
Line 3: We declare an iterator for our vector. It points at the memory address of the vector. We will use it for traversing the vector.
You can read up on iterators on the link provided at the end of this post.
Line 4: We make a function call to std::find that will return an iterator containing the position of key k in the vector.
Line 5 — 8: Here we do an if check, if the element is in the vector, we return its position otherwise we return -1 denoting that it is not in the vector.
The time complexity is linear O(n), this is because the function call goes through n items in the vector inorder to find the key we are searching for.
The space complexity is constant O(1), no extra space is used, just going through the vector and making comparisons.
2. Use std::find_if() with std::distance()
This is a recommended approach to finding an element in a vector if the search needs to satisfy a specific logic eg, finding an index of element in the vector that is a prime number using prime number logic.
std::find_if() returns an iterator to the first element in the first to last range for which our predicate(compare struct) returns true. If there is no such key, the function will return end(last), point past last.
std::distance() returns the number of hops from first to last. In our case it returns hops from begining of vector upto the iterator which points to the key k, this is the positional index of the element we are searching for. The number of hops will be the index of key k.
#include<bits/stdc++.h>
struct compare{
int k;
compare(int const &i): k(i) {}
bool operator()(int const &i) {
return (i == k);
}
};
int searchResult(std::vector<int> arr, int k){
auto itr = std::find_if(arr.cbegin(), arr.cend(), compare(k));
if(itr != arr.cend())
return std::distance(arr.cbegin(), itr);
return -1;
}
int main(){
std::vector<int> arr = {1, 2, 3, 4, 5, 6};
int k = 4;
std::cout << searchResult(arr, k) << std::endl;
return 0;
}
Code Explanation
The function searchResult() returns index of element in the vector or -1 denoting the absence of the element in the vector.
Line 2 — 8: We have declared a structure compare that compares the int k to values passed in its arguments.
You can read up on C++ structures at the external link provided at the end of this post.
Line 9: We declare a searchResult function that will take a vector and key as its parameters.
Line 10: Again we call the find_if function from STL libray but in this case we pass constant random access iterators that point to the begining (arr.cbegin()) and point past the end of the vector (arr.cend()) and the compare structure with key k as its parameter.
The auto keyword here specifies that the declared variable type will be automatically deducted from its initializer.
Line 10 — 13: We perform an if check to see if the iterator returned a value.
std::distance will perform as discussed above.
At this point it number of hops will be pointing to the index of key k in the vector.
The time complexity here is also linear O(n) because we got through the entire vector inorder to find the element.
The Space complexity is Constant O(1), no extra space is used.
Approach 2: Returning boolean value
3: Use std::count()
std::count() returns the number of occurences of an element in a vector.
We can apply it in situations where we need to check occurences of an element in the vector and return the number of times the element shows up in the vector.
#include<bits/stdc++.h>
bool searchResult(std::vector<int> arr, int k){
return std::count(arr.begin(), arr.end(), k);
}
int main(){
std::vector<int> arr = {1, 2, 3, 4, 5, 6};
int k = 4;
std::cout << searchResult(arr, k) << std::endl;
return 0;
}
Code Explanation
Line 2: The function searchResult() takes the vector arr and key k as its parameters.
It returns 1 denoting true and 0 denoting false.
Line 3: Count STL function counts occurences of key k, if there are any, it returns the number of element occurences.
We can do an if check, if the count is greater than 0 then tha element exists otherwise it doesnt.
The time complexity is linear O(n) as we go through the entire vector.
The space complexity is constant O(1) as no extra space is used.
Approach 3: Linear search
In this case we dont use any STL function but rather we traverse the vector using a for loop element by element and make comparisons between target and each element, if an element matches our target we return its index.
#include<bits/stdc++.h>
int searchResult(std::vector<int> arr, int k){
for(int i = 0; i < arr.size(); i++){
if(arr[i] == k){
return i;
}
}
return -1;
}
int main(){
std::vector<int> arr = {1, 4, 33, 44, 5, 6, 100, 4, 5, 7, 9, 0};
int k = 4;
std::cout << searchResult(arr, k) << std::endl;
return 0;
}
Code Explanation
The function takes a vector and key k as its parameters, if the element exists, it returns the index, otherwise it returns -1 denoting absence of the element.
Line 3: We use a for loop where we go through the vector making element and target comparisons.
Line 4: We do an if check, if the element at the index is equal to our target, we return the index, otherwise we exit the loop and return -1.
Question
What is the running time and space complexity of the above approach by linear search?
Can you explain why the time and space complexity is so?
References
- Iterators in C++
- Structures in C++
Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article
Given a vector V consisting of N integers and an element K, the task is to find the index of element K in the vector V. If the element does not exist in vector then print -1.
Examples:
Input: V = {1, 45, 54, 71, 76, 17}, K = 54
Output: 2
Explanation :
The index of 54 is 2, hence output is 2.
Input: V = {3, 7, 9, 11, 13}, K = 12
Output: -1
Approach:
Follow the steps below to solve the problem:
- find(): Used to find the position of element in the vector.
- Subtract from the iterator returned from the find function, the base iterator of the vector .
- Finally return the index returned by the subtraction.
Below is the implementation of the above approach :
C++
#include <bits/stdc++.h>
using
namespace
std;
void
getIndex(vector<
int
> v,
int
K)
{
auto
it = find(v.begin(), v.end(), K);
if
(it != v.end())
{
int
index = it - v.begin();
cout << index << endl;
}
else
{
cout <<
"-1"
<< endl;
}
}
int
main()
{
vector<
int
> v = { 1, 45, 54, 71, 76, 17 };
int
K = 54;
getIndex(v, K);
return
0;
}
Time Complexity: O(N)
Auxiliary Space: O(1)
Last Updated :
10 Jan, 2023
Like Article
Save Article