C++ <algorithm> std::is_permutation
The std::is_permutation
function template in C++ is used to determine if one sequence is a permutation of another. In other words, it checks whether two sequences contain the same elements, possibly in a different order. This function is part of the <algorithm> header and is available since C++11.
Syntax of std::is_permutation
template <class ForwardIterator1, class ForwardIterator2>
bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2);
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, BinaryPredicate pred);
Parameters of std::is_permutation
Parameter | Description |
---|---|
first1, last1 | Forward iterators defining the range [first1, last1) for the first sequence. |
first2 | Forward iterator to the beginning of the second sequence. The function considers as many elements of this sequence as those in the range [first1, last1) . If this sequence is shorter, it causes undefined behavior. |
pred (optional) | Binary predicate that accepts two elements as arguments (one from each of the two sequences, in the same order) and returns a value convertible to bool . The value returned 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::is_permutation
The function returns a boolean value:
true
if all the elements in the range[first1, last1)
compare equal to those of the range starting atfirst2
in any order.false
otherwise.
Examples for is_permutation
Example 1: Checking if Two Arrays are Permutations of Each Other
In this example, we use std::is_permutation
to check if two arrays of integers are permutations of each other.
Program
#include <iostream>
#include <algorithm>
#include <array>
int main() {
std::array<int, 5> array1 = {1, 2, 3, 4, 5};
std::array<int, 5> array2 = {3, 1, 4, 5, 2};
if (std::is_permutation(array1.begin(), array1.end(), array2.begin())) {
std::cout << "array1 and array2 contain the same elements.\n";
} else {
std::cout << "array1 and array2 do not contain the same elements.\n";
}
return 0;
}
Output
array1 and array2 contain the same elements.
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<algorithm>
for thestd::is_permutation
function, and<array>
for thestd::array
container. - We define two arrays,
array1
andarray2
, each containing five integers. The elements inarray2
are a permutation of those inarray1
. - We call
std::is_permutation
, passing iterators to the beginning and end ofarray1
, and the beginning ofarray2
. The function compares the elements in both arrays to determine if they are permutations of each other. - The function returns
true
since all elements inarray1
are present inarray2
, regardless of order. - We print a message indicating that the arrays contain the same elements.
Example 2: Using a Custom Predicate with std::is_permutation
In this example, we use std::is_permutation
with a custom predicate to check if two sequences are permutations of each other, 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};
if (std::is_permutation(vec1.begin(), vec1.end(), vec2.begin(), abs_equal)) {
std::cout << "vec1 and vec2 are permutations of each other based on absolute values.\n";
} else {
std::cout << "vec1 and vec2 are not permutations of each other based on absolute values.\n";
}
return 0;
}
Output
vec1 and vec2 are permutations of each other based on absolute values.
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<vector>
for thestd::vector
container,<algorithm>
for thestd::is_permutation
function, and<cmath>
for thestd::abs
function. - We define a custom predicate function
abs_equal
that returnstrue
if the absolute values of two integers are equal. - We initialize two vectors,
vec1
andvec2
, containing integers where corresponding elements have the same absolute values. - We call
std::is_permutation
, passing iterators to the beginning and end ofvec1
, the beginning ofvec2
, and the custom predicateabs_equal
. The function compares the elements using the custom predicate instead of the default equality operator. - The function returns
true
becausevec1
andvec2
contain the same elements when compared based on their absolute values. - We print a message indicating that the two vectors are permutations of each other based on absolute values.
Examples for Exceptions Thrown by std::is_permutation
The std::is_permutation
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 custom 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 = {4, 3, 2, 1};
try {
bool result = std::is_permutation(vec1.begin(), vec1.end(), vec2.begin(), faulty_predicate);
if (result) {
std::cout << "The sequences are permutations of each other.\n";
} else {
std::cout << "The sequences are not permutations of each other.\n";
}
} 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_predicate
that throws astd::runtime_error
if either of the input values is negative. - We initialize two vectors,
vec1
andvec2
. The first vector contains a negative value. - The
std::is_permutation
function applies the predicate to compare elements from both sequences. 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;
}
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[] = {4, 3, 2, 1};
try {
bool result = std::is_permutation(
FaultyIterator(arr1, true),
FaultyIterator(arr1 + 4),
FaultyIterator(arr2)
);
if (result) {
std::cout << "The sequences are permutations of each other.\n";
} else {
std::cout << "The sequences are not permutations of each other.\n";
}
} 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
FaultyIterator
that throws astd::runtime_error
after accessing two elements. - We create two arrays,
arr1
andarr2
, to compare as permutations. - The
std::is_permutation
function uses the custom iterator to compare the elements of both arrays. - The iterator throws an exception during the third access, which is caught in the
try-catch
block, and an error message is displayed.