标签:算法
本算法的思想也是希望以(12…n)
作为n个元素1,2,…,n的第一个排列,
然后按照某种方法,
由一个排列(p)=(p1p2…pn)直接生成下一个排列,
直到全部排列生成完毕为止。
以n=4为例,开始在排列1234的各数上方加一个左箭头“←”,
当一个数上方箭头所指的一侧,相邻的数比该数小时,
便称该数处于活动状态。
从排列(p)=(p1p2…pn)生成下一个排列的算法如下:
(1)若排列(p)=(p1p2…pn)中无一数处于活动状态,则停止,
否则转(2);
(2)求所有处于活动状态的数中的最大者,设为k,
k和它的箭头所指的一侧的相邻数互换位置,转(3);
(3)令比k大的所有数的箭头改变方向,转(1)。
算法如下:
请自行调试
*/
#include <iostream>
using namespace std;
enum DIR{LEFT=-1,RIGHT=1};
函数功能:判断下标i所指p中元素是否处于活动状态
输入参数:p ,指向n个字符的一个当前排列
dir ,标记p中每个元素的箭头方向
i ,待判定元素的下标
N ,待排列字符的个数
返回值: true 表示待判定元素为活动状态,
false 表示待判定元素处于非活动状态
bool IsActive(const char *p,const DIR *dir,const int i,const int N)
{
if(i+dir[i] < 0 || i+dir[i] >= N)return false;
if(p[i+dir[i]] < p[i]) //箭头所指一侧相邻的数比该数小
return true;
else return false;
}
函数功能:找到p中处于活动状态的数中的最大者
输入参数:p ,指向n个字符的一个当前排列
dir ,标记p中每个元素的箭头方向
N ,待排列字符的个数
返回值:上述最大者的下标,-1表示调用参数有误,N表示没有活动者
int MaxActive(const char *p,const DIR *dir,const int N)
{
int k=N;
for(int i=0;i<N;i++)
if(IsActive(p,dir,i,N) && (p[i] > p[k]))
k = i;
return k;
}
函数功能:交换下标i所指元素与其箭头方向所指元素,原位交换
输入参数:p ,指向n个字符的一个当前排列
dir ,标记p中每个元素的箭头方向
i ,待交换元素的下标
返回值: true 表示交换成功
false 表示交换失败,失败原因为调用参数有误。
bool Swap(char *p, DIR *dir, int *i)
{
if(p == NULL || dir == NULL)return false;
//交换相邻的元素;
char temp = p[*i];
p[*i] = p[*i+dir[*i]];p[*i+dir[*i]] = temp;
//元素相关的箭头也得交换
DIR T = dir[*i];dir[*i] = dir[*i+T];
dir[*i+T] = T;
*i = *i + T; //使*i依旧是未交换前*i所指元素的下标
return true;
}
函数功能:上述算法思路第三步,修改所以比k大的元素的箭头方向,原位修改
输入参数:p ,指向n个字符的一个当前排列
dir ,标记p中每个元素的箭头方向
k ,p中处于活动状态的最大者的下标,由MaxActive函数求出
N in,缓冲区p的长度,也是待排列字符的个数
返回值: true 表示函数执行成功
false 表示函数执行失败,失败原因为调用参数有误
bool ModifyDir(const char *p,DIR *dir,const int k,const int N)
{
if(p == NULL || dir == NULL)return false;
for(int i=0;i<N;i++)
if(p[i]>p[k])
dir[i] = (dir[i] == LEFT ? RIGHT : LEFT);
return true;
}
int main()
{
int N =0;cin>>N;
char *p = new char [N+1];
DIR *dir = new DIR [N];
for(int i=0;i<N;i++)
{
p[i] = ‘1‘+i;
dir[i] = LEFT;
}
p[N]=‘\0‘;
int k=0;
cout<<p;
int c = 1;
do
{
k = MaxActive(p,dir,N);
if(k == N)
break;
Swap(p,dir,&k);
ModifyDir(p,dir,k,N);
cout<<"->"<<p;
c++;
} while (1);
cout<<endl;
cout<<c<<endl;
delete []p;
delete []dir;
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:算法
原文地址:http://blog.csdn.net/qq_28236309/article/details/47265367