问题:输入n,从小到大输出从1到n,n个数的字典序
步骤:
1.初始化,将1~n从小到大存入buf数组
2.n个数的全排列有n!个,则调用n!次,并输出字典序。
3.my_next_permutation实现:
- 从后往前遍历buf数组,每次比较buf[i],buf[i+1],找到第一个正序序列,记下此时的下标a=i;
- 从a开始往后遍历,找到后n-a-1个数中大于buf[a]且最小的数,记下其下标b
- 调换buf[a],buf[b]
- 数组元素从a+1到n逆序
下面是代码实现:
#include <iostream>
#include <cstdio>
using namespace std;
int factorial(int n) {//计算阶乘
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
void my_next_permutation(int *buf,int n) {//计算字典序
int a;
for(int i=n-2; i>=0; i--) {//从后往前遍历,找到a
if(buf[i]<buf[i+1]) {
a=i;
break;
}
}
int b;
int min1=10;
for(int i=a; i<n; i++) {//从a向后遍历,找到符合要求的b
if(buf[i]>buf[a]&&buf[i]<min1) {
b=i;
min1=buf[i];
}
}
int temp=buf[a];//换位
buf[a]=buf[b];
buf[b]=temp;
for(int i=a+1; i<=(a+n-1)/2; i++) {//逆序
temp=buf[i];
buf[i]=buf[a+n-i];
buf[a+n-i]=temp;
}
}
int buf[10];
int main() {
int n;
cin>>n;
for(int i=0; i<n; i++) {
buf[i]=i+1;
}
for(int i=0; i<factorial(n); i++) {//n!次调用
for(int j=0; j<n; j++) {//输出
if(j==0)cout<<buf[j];
else cout<<' '<<buf[j];
}
cout<<endl;
my_next_permutation(buf,n);
}
return 0;
}