Approach & Description:
Generation in lexicographic order
There are many ways to systematically generate all permutations of a
given sequence. One classical algorithm, which is both simple and
flexible, is based on finding the next permutation in lexicographic ordering,
if it exists. It can handle repeated values, for which case it
generates the distinct multiset permutations each once. Even for
ordinary permutations it is significantly more efficient than generating
values for the Lehmer code in lexicographic order (possibly using the factorial number system) and converting those to permutations. To use it, one starts by sorting the sequence in (weakly) increasing
order (which gives its lexicographically minimal permutation), and then
repeats advancing to the next permutation as long as one is found.
The following algorithm generates the next permutation
lexicographically after a given permutation. It changes the given
permutation in-place.
- Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
- Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
- Swap a[k] with a[l].
- Reverse the sequence from a[k + 1] up to and including the final element a[n].
After step 1, one knows that all of the elements strictly after position k
form a weakly decreasing sequence, so no permutation of these elements
will make it advance in lexicographic order; to advance one must
increase a[k]. Step 2 finds the smallest value a[l] to replace a[k] by, and swapping them in step 3 leaves the sequence after position k
in weakly decreasing order. Reversing this sequence in step 4 then
produces its lexicographically minimal permutation, and the
lexicographic successor of the initial state for the whole sequence.
Final Algorithm:
1) From the end, keep decrementing till A[i] < A[i+1]..
2) Now, find the closest element , greater than equal, to A[i] in
A[i+1 ... n]. Say, the index of the found element is "j".
3) Swap (A[i], A[j])
4) Reverse array A[i+1 .. n]
Example:
Input 14532
output 15234..
1) 4 is the value where A[i] < A[i+1] when scanned from the end.
2) The closest element grater than equal to 4 in the subarray 532 is 5.
3) Swap (4,5) : 14532 -> 15432
4) Now, as we have identified in step 1 the index of i, we need to
reverse the array from A[i+1, n] i.e. in 15(432) (432) needs to be
reversed and hence we will get 15234...
Working Code
#include < iostream>
#include < algorithm>
#include < time.h>
using
namespace
std;
template
<
class
T>
void
swap(T *i, T *j)
{
T temp = *i;
*i = *j;
*j = temp;
}
template
<
class
T>
void
reverse(T *start, T *end)
{
while
(start < end)
{
swap(start,end);
start++;
end--;
}
}
template
<
class
T>
bool
permute(T* array_start,T* array_end)
{
if
(array_start == array_end)
return
false
;
if
(array_start+1 == array_end)
return
false
;
T *i,*i1,*j;
i = array_end - 2;
i1 = array_end - 1;
while
(
true
)
{
if
(*i < *i1)
{
j = array_end -1;
while
(!(*i < *j))
j--;
swap(i,j);
reverse(i1,array_end-1);
return
true
;
}
if
(i == array_start)
{
reverse(array_start,array_end-1);
return
false
;
}
i--;
i1--;
}
}
template
<
class
T>
void
display(T *array,T *end)
{
T* i = array;
while
(i < end)
{
cout << *i <<
"-"
;
i++;
}
cout << endl;
}
int
main()
{
srand
(
time
(NULL));
int
size = 4;
char
array[size];
cout <<
"Enter four numbers"
<< endl;
for
(
int
i=0;i < size;i++)
cin>>array[i];
sort(array,array+4);
display(array,array+4);
int
count=1;
while
(permute(array,array+4))
{
count++;
display(array,array+4);
}
cout <<
"Total permutations are "
<< count << endl;
system
(
"pause"
);
return
0;
}