//方法一,利用STL中的全排列算法
#include<iostream>
#include <algorithm>
using namespace std;
int main(){
int a[] = {1,2,3};
do{
cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (next_permutation(a,a+3)); //next_permutation(a,a+3)该方法是按字典顺序求出序列a+0~a+3的下一个序列并存回到数组中返回true,直到没有下一个序列返回false
return 0;
}
//方法二,利用规律找到下一个排列
//要求输入n(2~9)输出满足要求(1不在第一个位置,2不在第二个位置等)的排列
//效率不高,重在理解取得下一个排列的方法
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
vector<int> fn(vector<int> v){ //按字典顺序找出当前序列的下一个排列
vector<int> rev = v;
int s=0;
int e=0;
for(int i = rev.size()-1; i>0; i--){ //找到从左数第一个左邻<右邻的左邻下表
if(rev[i-1] < rev[i]){
s = i-1; //s左邻下表
break;
}
}
for(int j = rev.size()-1; j>0; j--){
if(rev[s]<rev[j]){ //找到从左数第一个大于rev[s]的值的下表
e=j; //e找的的下表
break;
}
}
char temp = rev[e]; //rev[s] <-->rev[e]交换
rev[e] = rev[s];
rev[s] = temp;
sort(rev.begin()+s+1,rev.end()); //将rev[s]之后的数进行从小到大的排序
return rev;
}
int fnj(int n){ //求阶乘,所有全排列的个数,总共循环的次数
int result = 1;
for(int i=1;i<=n;i++){
result = result * i;
}
return result;
}
void printv(vector<int> v){ //输出向量中的内容
for(int i=0; i<v.size(); i++){
printf("%d ",v[i]);
}
cout<<endl;
}
bool right(vector<int> v){ //是否满足1不在第一个位置,2不在第二个位置等要求
for(int i=1; i<=v.size(); i++){
if(i == v[i-1]){
// cout<<i<<"-->"<<v[i-1];
return false;
}
}
return true;
}
int main(){
int count;
cin>>count;
// int n = fnj(count); //也可以用阶乘来控制
vector<int> test;
for(int i=1;i<=count;i++){
test.push_back(i);
}
vector<int> retest = test;
reverse(retest.begin(),retest.end());
while(1){
test = fn(test);
if(right(test))
printv(test);
if(test == retest) //如果到输出到最后一个了,则退出
return 0;
}
return 0;
}
还有许多方法求出全排列(递归求解等)