C++ <algorithm> std::equal
The std::equal function template in C++ is used to determine if two sequences are equal by comparing their elements pairwise. It is included in the <algorithm> header and provides a convenient way to compare ranges of elements.
Syntax of std::equal
template <class InputIterator1, class InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred);
Parameters of std::equal
| Parameter | Description |
|---|---|
first1, last1 | Input iterators defining the range [first1, last1) for the first sequence. |
first2 | Input iterator to the beginning of the second sequence. The function compares elements in the range starting from first2 up to the distance [first1, last1). |
pred (optional) | Binary predicate that takes two elements as arguments (one from each sequence) and returns a boolean indicating whether they are considered equal. If not provided, the function uses operator== by default. |
Return Value of std::equal
The function returns a boolean value:
trueif all the elements in the range[first1, last1)compare equal to those of the range starting atfirst2.falseotherwise.
Examples for algorithm equal function
Example 1: Comparing Two Arrays for Equality
In this example, we use std::equal to check if two arrays of integers are equal.
Program
#include <iostream>
#include <algorithm>
int main() {
int array1[] = {1, 2, 3, 4, 5};
int array2[] = {1, 2, 3, 4, 5};
bool are_equal = std::equal(std::begin(array1), std::end(array1), std::begin(array2));
if (are_equal) {
std::cout << "The arrays are equal." << std::endl;
} else {
std::cout << "The arrays are not equal." << std::endl;
}
return 0;
}
Output
The arrays are equal.
Explanation
- We include the necessary headers:
<iostream>for input/output operations and<algorithm>for thestd::equalfunction. - We define two arrays,
array1andarray2, each containing five integers with identical values. - We call
std::equal, passing iterators to the beginning and end ofarray1, and the beginning ofarray2. The function compares corresponding elements from both arrays. - The function returns
truesince all corresponding elements are equal. - We print a message indicating that the arrays are equal.
Example 2: Comparing Two Vectors with a Custom Predicate
In this example, we use std::equal with a custom predicate to compare two vectors of integers, considering elements equal if their absolute values are the same.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
bool abs_equal(int a, int b) {
return std::abs(a) == std::abs(b);
}
int main() {
std::vector<int> vec1 = {1, -2, 3, -4, 5};
std::vector<int> vec2 = {1, 2, 3, 4, 5};
bool are_equal = std::equal(vec1.begin(), vec1.end(), vec2.begin(), abs_equal);
if (are_equal) {
std::cout << "The vectors are equal based on absolute values." << std::endl;
} else {
std::cout << "The vectors are not equal based on absolute values." << std::endl;
}
return 0;
}
Output
The vectors are equal based on absolute values.
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<vector>for thestd::vectorcontainer,<algorithm>for thestd::equalfunction, and<cmath>for thestd::absfunction. - We define a custom predicate function
abs_equalthat returnstrueif the absolute values of two integers are equal. - We create two vectors,
vec1andvec2, containing integers with corresponding elements having the same absolute values. - We call
std::equal, passing iterators to the beginning and end ofvec1, the beginning ofvec2, and the custom predicateabs_equal. The function compares corresponding elements using the custom predicate. - The function returns
truesince all corresponding elements are equal based on their absolute values. - We print a message indicating that the vectors are equal based on absolute values.
Example 3: Checking for Palindrome Using std::equal
In this example, we use std::equal to check if a string is a palindrome by comparing its characters with their counterparts in reverse order.
Program
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string str = "radar";
bool is_palindrome = std::equal(str.begin(), str.begin() + str.size() / 2, str.rbegin());
if (is_palindrome) {
std::cout << "The string \"" << str << "\" is a palindrome." << std::endl;
} else {
std::cout << "The string \"" << str << "\" is not a palindrome." << std::endl;
}
return 0;
}
Output
The string "radar" is a palindrome.
Explanation
- We include the necessary headers:
<iostream>for input/output operations,<string>for thestd::stringclass, and<algorithm>for thestd::equalfunction. - We define a string
strinitialized with the value “radar”. - We call
std::equalto compare the first half of the string with its reverse counterpart. This is achieved by iterating from the beginning of the string to the middle (str.begin() + str.size() / 2) and comparing it with the reverse iteratorstr.rbegin(). - If all corresponding characters match,
std::equalreturnstrue, indicating that the string is a palindrome. - The result is stored in
is_palindrome, which is then used to print an appropriate message indicating whether the string is a palindrome.
Examples for Exceptions Thrown by std::equal
The std::equal function can throw exceptions in the following scenarios:
- If the element comparison or the 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> vec1 = {1, -2, 3, 4};
std::vector<int> vec2 = {1, 2, 3, 4};
try {
bool are_equal = std::equal(vec1.begin(), vec1.end(), vec2.begin(), faulty_predicate);
if (are_equal) {
std::cout << "The vectors are equal." << std::endl;
} else {
std::cout << "The vectors are not equal." << 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
- We define a custom predicate
faulty_predicatethat throws astd::runtime_errorif either input value is negative. - We initialize two vectors,
vec1andvec2, wherevec1contains a negative value. - The
std::equalfunction applies the predicate to corresponding elements from both vectors. 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.
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;
}
private:
const int* ptr;
bool fail_after;
int count;
};
int main() {
int arr1[] = {1, 2, 3, 4};
int arr2[] = {1, 2, 0, 4};
try {
bool are_equal = std::equal(
FaultyIterator(arr1, true),
FaultyIterator(arr1 + 4),
FaultyIterator(arr2)
);
if (are_equal) {
std::cout << "The sequences are equal." << std::endl;
} else {
std::cout << "The sequences are not equal." << std::endl;
}
} catch (const std::runtime_error& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
Output
Exception caught: Iterator error during dereference.
Explanation
- We define a custom iterator
FaultyIteratorthat throws astd::runtime_errorafter accessing two elements. - We create two arrays,
arr1andarr2, for comparison. - The
std::equalfunction uses the custom iterator to compare the elements in both arrays. - The iterator throws an exception during the third access, which is caught in the
try-catchblock, and an error message is printed.
