题意:此题为一道考察字典序生成算法的题目。给定一个有(A-Z)组成的字符串按字典序进行排列排列。如一个字符串为“BAC” 则应输出ABC ACB BAC BCA CAB CBA的字符串排列。
字典序算法思想:
从自然顺序123…n开始,按照字典顺序依次构造集合{1, 2, …, n}的所有全排列,由一个排列构造下一个排列的算法如下:
1.对p1 p2 …pn 从右向左扫描,找出比右邻数字小的第1个数pi
2.对p1 p2 …pn 从右向左扫描,找出比pi 大的第一个数pj
3.将pi 和pj 互换得b1 b2 …bn
4.将b1 b2 …bn 中的bi+1 到bn 部分的顺序逆转,得b1 b2 …bn …bi+1
具体算法如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
inline void swap(int &a,int &b){ //交换函数
int temp;
temp=a;
a=b;
b=temp;
}
void Print(int a[],int n){ //打印输出函数
for(int i=1;i<=n;i++){
printf("%c",a[i]+'0');
if(i==n) cout<<"\n";
}
return ;
}
int main(){
int Dire[30],q;
char a[30];
int r,l,n,t;
int count=0,c=1;
scanf("%d",&t);//输入测试用例数
while(t--){
scanf("%s",a); //输入字符串
n=strlen(a);//求字符串长度
sort(a,a+n);//将字符串排序 形成初始排列
printf("Case %d:\n",c++);
for(int i=1;i<=n;i++){//将字符串转化为数字
Dire[i]=a[i-1]-'0';
printf("%c",Dire[i]+'0');
if(i==n) printf("\n");
}
int i=n-1;// i从倒数第二位开始
while(i>0){
if(Dire[i]<Dire[i+1]){//从右向左寻找 <span style="font-family: Arial, Helvetica, sans-serif;">Dire[i]<Dire[i+1]</span>
l=i; //记下i的位置
for(int j=n;j>l;j--){
if(Dire[j]>Dire[l]){ //从右向左寻找第一个大于<span style="font-family: Arial, Helvetica, sans-serif;">Dire[j]的数</span>
r=j;
break;
}
}
swap(Dire[l],Dire[r]); //交换Dire[j]>Dire[i]
for(int p=l+1,q=n;p<q;p++,q--)//倒序
swap(Dire[p],Dire[q]);
Print(Dire,n);
i=n-1;
}
else
i--;
}
}
return 0;
}