/**
顾名思义,这种方法的思想就是将所有n元排列按“字典顺序”排成队,
以12…n为第一个排列,排序的规则,也就是由一个排列(p)=(p1p2…pn)
直接生成下一个排列的算法可归结为
(1) 求满足关系式P[k-1]<P[k]的k的最大值,设为i,即
i = max{k|P[k-1] < P[k]};
(2) 求满足关系式P[i-1]<P[k]的k的最大值,设为j,即
j = max{k|P[i-1] < P[k]};
(3) P[i-1]与P[j]互换位置得
(q)=(q1 q2 … qn);
(4) (q)=(q1 q2 … qi-1 qi qi+1 … qn)中qi qi+1 … qn部分的顺序逆转,得新排列
q1 q2 … qi-1 qn…qi+1 qi
示例:
当 n=4 时,由字典序法所得的全部排列的先后顺序如下:
1234 → 1243 → 1324 → 1342 → 1423 → 1432 → 2134 →
2143 → 2314 → 2341 → 2413 → 2431 → 3124 → 3142 →
3214 → 3241 → 3412 → 3421 → 4123 → 4132 → 4213 →
4231 → 4312 → 4321
*/
#include <iostream>
using namespace std;
/* 函数功能:求出满足关系式P[k-1]<P[k]的k的最大值.
* 输入参数: p in,指向n个字符的一个排列
* N in,p所指缓冲区的长度
* 返回值:上述描述所需的i值,-1表示调用参数有误
*/
int iMax(const char *p,const int N)
{
if(p == NULL)
return -1;
int maxi = 0;
for(int k=1;k<N;k++)
if(p[k-1]<p[k])
{
maxi = k;
}
return maxi;
}
/* 函数功能:求出满足关系式P[i-1]<P[k]的k的最大值
* 输入参数: P in,指向n个字符的一个排列
* i in,关系式中的i值,由iMax函数求出
* N in,p所指缓冲区的长度
* 返回值:上述描述所需的j值,-1表示调用参数有误
*/
int jMax(const char *p,const int i,const int N)
{
if(p == NULL)
return -1;
int maxj = 0;
for(int k=0;k < N;k++)
if(p[i-1]<p[k])
maxj = k;
return maxj;
}
/* 函数功能,交换指针p1和p2所指的变量值
*/
bool swap(char *p1,char *p2)
{
if( p1 == NULL || p2 == NULL)
return false;
char temp = *p1;
*p1 = *p2;
*p2 = temp;
return true;
}
/* 函数功能:将ps和pe所指区间内容逆序
*/
bool reverse(char *ps,char *pe)
{
if(ps == NULL || pe == NULL)
return false;
while(ps<pe)
{
swap(ps++,pe--);
}
return true;
}
int main()
{
int N;
cin >>N;
char *array = new char[N+1];
char *endArray = new char[N+1];
for(int i=0;i<N;i++)
array[i]=endArray[N-i-1]='1'+i;
array[N]=endArray[N]='\0';
int c=1;
int i=0;
int j=0;
cout<<array;
do{
i = iMax(array,N);
j = jMax(array,i,N);
swap(array+i-1,array+j);
reverse(array+i,array+N-1);
cout<<"->"<<array;
c++;
}while(strcmp(array,endArray));
cout<<endl;
cout<<c<<endl;
delete [] array;
delete [] endArray;
return 0;
}
运行结果: