第一种方法:递归
待求数组排列中不能有重复元素
void perm(int a[],int cnt){
if(cnt==n+1){
cout<<.....;
return ;
}
else{
依次考虑a数组中的每个元素v
perm(在s中添加v构成新数列);//s为储存数组
}
#include<bits/stdc++.h>
using namespace std;
bool x[12];//记录此数是否已经选入xx数组中
int xx[13];
int n;
int s[13]; //需要进行全排列的数组
void p_search(int a)
{
if(a==n+1)
{
for(int i=1;i<=n;++i)
{
printf("%5d",xx[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;++i)
{
if(!x[s[i]])
{
xx[a]=s[i];
x[s[i]]=true;
p_search(a+1);// p_search(++a);是错的,因为不仅改变了参数值,还改变了本次递归中a值
x[s[i]]=false;//回溯阶段要清除标记
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>s[i];
p_search(1);
}
可重集的排列
void perm(int a[],int cnt){
if(cnt==n+1){
cout<<.....;
return ;
}
else{
依次考虑a数组中的每个元素v
for(int i=1;i<=n;;i++)
i应该不重复取遍所有的a[i],因为每次循环调用的递归都是以a[i]为开头的序列
if(i==1||a[i]!=a[i-1])//已经对a数组排序
perm(在s中添加v构成新数列);//s为储存数组
}
#include<bits/stdc++.h>
using namespace std;
int f1[100],f2[100];
int b[100],n;
void perm(int a[],int cnt){
if(cnt==n+1){
for(int i=1;i<=n;i++)
cout<<b[i]<<" ";
cout<<endl;
return ;
}
for(int i=1;i<=n;i++){
if(i==1||a[i]!=a[i-1]){
if(f1[a[i]]>f2[a[i]]){
++f2[a[i]];
b[cnt]=a[i];
perm(a,cnt+1);
--f2[a[i]];
}
}
}
}
int main(){
cin>>n;
int a[100];
for(int i=1;i<=n;i++){
cin>>a[i];
f1[a[i]]++;
}
sort(a+1,a+1+n);
perm(a,1);
}
下一个排列(库函数)
#include<bits/stdc++.h>
using namespace std;
int f1[100],f2[100];
int b[100],n;
int main(){
int n;
cin>>n;
int a[100];
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
do{
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}while(next_permutation(a+1,a+n+1));
return 0;
}