C++ <algorithm> std::find_end
The std::find_end function in C++ is part of the <algorithm> header and is used to find the last occurrence of a subsequence within a container. It searches for the last occurrence of a sequence defined by a range [first2, last2) within another range [first1, last1), and returns an iterator to the first element of this last occurrence. If the subsequence is not found, it returns last1.
Syntax of std::find_end
template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2);
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred);
Parameters of std::find_end
| Parameter | Description |
|---|---|
first1, last1 | Forward iterators to the initial and final positions of the searched sequence. The range used is [first1, last1), which contains all the elements between first1 and last1, including the element pointed by first1 but not the element pointed by last1. |
first2, last2 | Forward iterators to the initial and final positions of the sequence to be searched for. The range used is [first2, last2). |
pred | Binary function that accepts two elements as arguments (one of each of the two sequences, in the same order), and returns a value convertible to bool. The returned value indicates whether the elements are considered to match in the context of this function. The function shall not modify any of its arguments. This can either be a function pointer or a function object. |
Return Value of std::find_end
An iterator to the first element of the last occurrence of [first2, last2) in [first1, last1). If the sequence is not found, the function returns last1. If [first2, last2) is an empty range, the result is unspecified.
Examples for find_end
Example 1: Using std::find_end to Find the Last Occurrence of a Subsequence
In this example, we use std::find_end to find the last occurrence of a subsequence within a vector.
Program
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> main_sequence = {1, 2, 3, 4, 2, 3, 4, 5};
std::vector<int> sub_sequence = {2, 3, 4};
auto it = std::find_end(main_sequence.begin(), main_sequence.end(),
sub_sequence.begin(), sub_sequence.end());
if (it != main_sequence.end()) {
std::cout << "Last occurrence of subsequence found at position: "
<< std::distance(main_sequence.begin(), it) << '\n';
} else {
std::cout << "Subsequence not found.\n";
}
return 0;
}
Output
Last occurrence of subsequence found at position: 4
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<vector>for thestd::vectorcontainer, and<algorithm>for thestd::find_endfunction. - We define a vector
main_sequencecontaining the integers {1, 2, 3, 4, 2, 3, 4, 5}. - We define another vector
sub_sequencecontaining the integers {2, 3, 4}. - We use
std::find_endto search for the last occurrence ofsub_sequencewithinmain_sequence. - If the subsequence is found,
itpoints to the first element of the last occurrence, and we print its position usingstd::distance. Otherwise, we print that the subsequence was not found.
Example 2: Using std::find_end with a Custom Comparator
This example demonstrates how to use std::find_end with a custom comparator to find the last occurrence of a subsequence within a list, ignoring case sensitivity.
Program
#include <iostream>
#include <list>
#include <algorithm>
#include <cctype>
bool case_insensitive_compare(char a, char b) {
return std::tolower(a) == std::tolower(b);
}
int main() {
std::list<char> main_sequence = {'A', 'b', 'C', 'd', 'B', 'c', 'D', 'e'};
std::list<char> sub_sequence = {'b', 'C', 'd'};
auto it = std::find_end(main_sequence.begin(), main_sequence.end(),
sub_sequence.begin(), sub_sequence.end(),
case_insensitive_compare);
if (it != main_sequence.end()) {
std::cout << "Last occurrence of subsequence found at position: "
<< std::distance(main_sequence.begin(), it) << '\n';
} else {
std::cout << "Subsequence not found.\n";
}
return 0;
}
Output
Last occurrence of subsequence found at position: 4
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<list>for thestd::listcontainer,<algorithm>for thestd::find_endfunction, and<cctype>for thestd::tolowerfunction used in the custom comparator. - We define a custom comparator function
case_insensitive_comparethat compares two characters in a case-insensitive manner by converting both to lowercase usingstd::tolower. - We define a list
main_sequencecontaining the characters {‘A’, ‘b’, ‘C’, ‘d’, ‘B’, ‘c’, ‘D’, ‘e’}. - We define another list
sub_sequencecontaining the characters {‘b’, ‘C’, ‘d’}. - We use
std::find_endwith the custom comparator to search for the last occurrence ofsub_sequencewithinmain_sequence, ignoring case sensitivity. - If the subsequence is found,
itpoints to the first element of the last occurrence, and we print its position usingstd::distance. Otherwise, we print that the subsequence was not found.
Examples for Exceptions Thrown by std::find_end
The std::find_end function can throw exceptions in the following cases:
- If the comparison operation or predicate function (
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> main_sequence = {1, -2, 3, -2, 3, 4};
std::vector<int> sub_sequence = {-2, 3};
try {
auto it = std::find_end(main_sequence.begin(), main_sequence.end(),
sub_sequence.begin(), sub_sequence.end(),
faulty_predicate);
if (it != main_sequence.end()) {
std::cout << "Subsequence found at position: "
<< std::distance(main_sequence.begin(), it) << std::endl;
} else {
std::cout << "Subsequence not found." << std::endl;
}
} catch (const std::runtime_error& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
Output
Exception caught: Negative value encountered during comparison.
Explanation
- The program defines a predicate function
faulty_predicatethat throws astd::runtime_errorif either of the values being compared is negative. - The vector
main_sequencecontains both positive and negative integers. - The vector
sub_sequencecontains integers, including a negative value. - The
std::find_endfunction applies the predicate to search for the last occurrence ofsub_sequenceinmain_sequence. When the predicate encounters a negative value, it throws an exception. - The exception is caught in the try-catch block, and an error message is printed.
