C++ Algorithm: std::adjacent_find
The std::adjacent_find
function in C++ is part of the <algorithm> header and is used to identify the first occurrence of two consecutive identical elements in a range. It returns an iterator to the first element of this pair. If no such pair is found, it returns the end iterator.
Syntax of std::adjacent_find
template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last);
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
BinaryPredicate pred);
Parameters of std::adjacent_find
Parameter | Description |
---|---|
first, last | Forward iterators defining the range to be examined. The range used is [first, last) , which includes all elements between first and last , excluding the element pointed to by last . |
pred | (Optional) A binary function that takes two elements as arguments and returns a boolean value. It defines the condition to be satisfied for two consecutive elements to be considered a match. The function should not modify its arguments. |
Return Value of std::adjacent_find
An iterator to the first element of the first pair of matching consecutive elements in the specified range. If no such pair is found, the function returns last
.
Example: Using std::adjacent_find to Find Consecutive Duplicate Elements
In this example, we use std::adjacent_find
to locate the first occurrence of consecutive duplicate elements in a vector.
Program
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> numbers = {1, 2, 3, 3, 4, 5};
auto it = std::adjacent_find(numbers.begin(), numbers.end());
if (it != numbers.end()) {
std::cout << "First pair of adjacent duplicates found at position "
<< std::distance(numbers.begin(), it)
<< " with value " << *it << ".\n";
} else {
std::cout << "No adjacent duplicates found.\n";
}
return 0;
}
Output
First pair of adjacent duplicates found at position 2 with value 3.
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<vector>
for thestd::vector
container, and<algorithm>
for thestd::adjacent_find
function. - We define a vector
numbers
containing the integers {1, 2, 3, 3, 4, 5}. - We use
std::adjacent_find
to search for the first occurrence of consecutive duplicate elements innumbers
. - If such a pair is found,
it
points to the first element of the pair, and we print its position and value. Otherwise, we print that no adjacent duplicates were found.
Example: Using std::adjacent_find with a Custom Comparator
This example demonstrates how to use std::adjacent_find
with a custom comparator to find the first occurrence of two consecutive elements that satisfy a specific condition.
Program
#include <iostream>
#include <vector>
#include <algorithm>
bool difference_of_one(int a, int b) {
return std::abs(a - b) == 1;
}
int main() {
std::vector<int> numbers = {1, 2, 4, 5, 7, 8};
auto it = std::adjacent_find(numbers.begin(), numbers.end(), difference_of_one);
if (it != numbers.end()) {
std::cout << "First pair of adjacent elements with a difference of one found at position "
<< std::distance(numbers.begin(), it)
<< " with values " << *it << " and " << *(it + 1) << ".\n";
} else {
std::cout << "No adjacent elements with a difference of one found.\n";
}
return 0;
}
Output
First pair of adjacent elements with a difference of one found at position 0 with values 1 and 2.
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<vector>
for thestd::vector
container, and<algorithm>
for thestd::adjacent_find
function. - We define a custom comparator function
difference_of_one
that returnstrue
if the absolute difference between two integers is 1. - We define a vector
numbers
containing the integers {1, 2, 4, 5, 7, 8}. - We use
std::adjacent_find
with the custom comparator to search for the first pair of adjacent elements innumbers
that have a difference of one. - If such a pair is found,
it
points to the first element of the pair, and we print its position and the values of both elements. Otherwise, we print that no such adjacent elements were found.
Examples for Exceptions Thrown by std::adjacent_find
The std::adjacent_find
function can throw exceptions in the following cases:
- If the comparison operation or predicate (
pred
) throws an exception. - If an operation on the iterators, such as dereferencing or incrementing, throws an exception.
Example 1: Predicate Throws an Exception
This example demonstrates a case where the predicate function throws an exception during execution.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
bool faulty_predicate(int a, int b) {
if (a < 0 || b < 0) {
throw std::runtime_error("Negative value encountered during comparison.");
}
return a == b;
}
int main() {
std::vector<int> numbers = {1, -2, -2, 4, 5};
try {
auto it = std::adjacent_find(numbers.begin(), numbers.end(), faulty_predicate);
if (it != numbers.end()) {
std::cout << "First adjacent pair found with value: " << *it << '\n';
} else {
std::cout << "No adjacent pair found.\n";
}
} catch (const std::runtime_error& e) {
std::cout << "Exception caught: " << e.what() << '\n';
}
return 0;
}
Output
Exception caught: Negative value encountered during comparison.
Explanation
- The program defines a predicate function
faulty_predicate
that throws astd::runtime_error
if either value being compared is negative. - The vector
numbers
contains integers, including negative values. - The
std::adjacent_find
function applies the predicate to each pair of consecutive elements innumbers
. When the predicate encounters negative values, it throws an exception. - The exception is caught in the try-catch block, and an error message is printed.
Example 2: Iterator Throws an Exception
This example demonstrates a case where a custom iterator throws an exception during iteration.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
class FaultyIterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using difference_type = std::ptrdiff_t;
using pointer = const int*;
using reference = const int&;
FaultyIterator(const int* ptr, bool fail_after = false)
: ptr(ptr), fail_after(fail_after), count(0) {}
reference operator*() const {
if (fail_after && count >= 2) {
throw std::runtime_error("Iterator error during dereference.");
}
return *ptr;
}
FaultyIterator& operator++() {
++ptr;
++count;
return *this;
}
bool operator!=(const FaultyIterator& other) const {
return ptr != other.ptr;
}
bool operator==(const FaultyIterator& other) const {
return ptr == other.ptr;
}
private:
const int* ptr;
bool fail_after;
int count;
};
int main() {
int arr[] = {1, 2, 2, 3, 4};
try {
auto it = std::adjacent_find(
FaultyIterator(arr, true),
FaultyIterator(arr + 5)
);
if (it != FaultyIterator(arr + 5)) {
std::cout << "First adjacent pair found with value: " << *it << '\n';
} else {
std::cout << "No adjacent pair found.\n";
}
} catch (const std::runtime_error& e) {
std::cout << "Exception caught: " << e.what() << '\n';
}
return 0;
}
Output
Exception caught: Iterator error during dereference.
Explanation
- The program defines a custom iterator
FaultyIterator
that throws astd::runtime_error
after accessing two elements. - An array
arr
contains five elements. - The
std::adjacent_find
function uses the custom iterator to search for the first adjacent pair of elements in the array. - The iterator throws an exception during the third access, which is caught in the
try-catch
block, and an error message is printed.