C++ std::next_permutation
The algorithm std::next_permutation function rearranges the elements in a range into the next lexicographically greater permutation. If such a permutation is not possible (i.e., the elements are sorted in descending order), it rearranges the elements into the smallest (i.e., sorted in ascending order) permutation and returns false. This function is useful in generating permutations of a range.
Syntax of std::next_permutation
template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last);
template <class BidirectionalIterator, class Compare>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Compare comp);
Parameters of std::next_permutation
| Parameter | Description |
|---|---|
first, last | Bidirectional iterators defining the range of elements to permute. The range is [first, last). |
comp (optional) | A binary comparison function that defines the criteria for comparing two elements. Defaults to <. |
Return Value of std::next_permutation
Returns true if the function successfully rearranges the elements into the next permutation. Returns false if the elements are rearranged into the smallest permutation (i.e., sorted in ascending order).
Examples for std::next_permutation
Example 1: Basic Usage of std::next_permutation
This example demonstrates generating all permutations of a vector:
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<int> nums = {1, 2, 3};
do {
for (int n : nums) {
std::cout << n << " ";
}
std::cout << std::endl;
} while (std::next_permutation(nums.begin(), nums.end()));
return 0;
}
Explanation:
- Include necessary headers:
<iostream>: Used for input/output operations.<algorithm>: Includes thestd::next_permutationfunction.<vector>: Used for thestd::vectorcontainer.
- Initialize a vector:
- A vector named
numsis created and initialized with the elements{1, 2, 3}. - The elements in the vector are arranged in ascending order, which is required for
std::next_permutationto generate all permutations.
- A vector named
- Generate permutations:
- The program uses a do-while loop to iterate through all permutations of the elements in
nums. - The function
std::next_permutationrearranges the elements in the next lexicographical order and returnstrueif the rearrangement is possible. If no more permutations exist, it returnsfalse.
- The program uses a do-while loop to iterate through all permutations of the elements in
- Print each permutation:
- Inside the loop, the program uses a for loop to iterate through the elements of the current permutation in
numsand prints them separated by spaces. - After printing the elements of a permutation, a newline character is added to separate the outputs.
- Inside the loop, the program uses a for loop to iterate through the elements of the current permutation in
- Continue until all permutations are generated:
- The
do-whileloop continues untilstd::next_permutationreturnsfalse, which happens when all permutations have been generated.
- The
Output:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Example 2: Using a Custom Comparison Function for std::next_permutation
This example demonstrates generating permutations based on a custom comparison function:
#include <iostream>
#include <algorithm>
#include <vector>
bool descending(int a, int b) {
return a > b;
}
int main() {
std::vector<int> nums = {3, 2, 1};
do {
for (int n : nums) {
std::cout << n << " ";
}
std::cout << std::endl;
} while (std::next_permutation(nums.begin(), nums.end(), descending));
return 0;
}
Explanation:
- Define a custom comparison function:
- The function
descendingtakes two integers as input. - It returns
trueif the first integer is greater than the second, ensuring that permutations are generated in descending order.
- The function
- Generate permutations:
- The program uses a
do-whileloop to iterate through all permutations of the elements innums. - The function
std::next_permutationis called with the rangenums.begin()andnums.end(), and the custom comparison functiondescendingas the third argument. - It rearranges the elements in the next descending lexicographical order and returns
trueif the rearrangement is possible. If no more permutations exist, it returnsfalse.
- The program uses a
Output:
3 2 1
3 1 2
2 3 1
2 1 3
1 3 2
1 2 3
Exception Handling in std::next_permutation
The std::next_permutation function does not throw exceptions on its own. However, the comparison function passed as an argument may throw exceptions, which can be caught and handled appropriately.
Example 1: Exception in Custom Comparison Function
This example demonstrates how exceptions in a custom comparison function are handled:
#include <iostream>
#include <algorithm>
#include <vector>
#include <stdexcept>
bool faulty_compare(int a, int b) {
if (a == 2 || b == 2) {
throw std::runtime_error("Comparison involving 2 is not allowed.");
}
return a < b;
}
int main() {
std::vector<int> nums = {1, 2, 3};
try {
do {
for (int n : nums) {
std::cout << n << " ";
}
std::cout << std::endl;
} while (std::next_permutation(nums.begin(), nums.end(), faulty_compare));
} catch (const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
Explanation:
- Define a custom comparison function:
- The function
faulty_comparecompares two integers,aandb. - If either
aorbequals2, the function throws an exceptionstd::runtime_errorwith the message"Comparison involving 2 is not allowed.". - Otherwise, it returns
trueifais less thanb.
- The function
- Handle exceptions:
- If
faulty_comparethrows an exception, thecatchblock captures it and prints the exception message usingstd::cerr.
- If
Output:
1 2 3
Exception caught: Comparison involving 2 is not allowed.
