大佬們的寫的很好:
全排列1
全排列2
全排列3 這第三個鏈接裏去重全排列那一塊兒的去重似乎不太對,可以考慮下面我的思考與實現
類似於這位大佬的實現:全排列4
next_permutation實現:
(從小到大按字典序輸出下一個排列)
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int data[4] = {5, 2, 1, 4};
sort(data,data+4);
do{
for(int i=0; i<4; i++){
cout<<data[i]<<" ";
}
cout<<endl;
}while(next_permutation(data,data+4));
return 0;
}
運行結果:
遞歸實現:
#include <iostream>
using namespace std;
#define Swap(a,b){int temp=a; a=b; b=temp;} //交換
int data[] = {1,3,5,7};
int num = 0;
void Perm(int begin, int end)
{
int i;
if(begin == end){ //遞歸結束,產生一個全排列(一個葉節點)
for(int j=0; j<3; j++){ //打印全排列
cout<<data[j]<<" ";
}
cout<<data[3]<<endl;
num++; //統計全排列個數
}else //沒到葉節點就遞歸下去
for(i = begin; i<=end; i++){
Swap(data[begin],data[i]); //八當前的第i個數與後面的所有數交換位置
Perm(begin+1,end);
Swap(data[begin],data[i]); //恢復上一級,用於下一次交換
}
}
int main()
{
Perm(0, 3);
cout<<"全排列的個數:"<<num<<endl;
return 0;
}
運行結果:
去重全排列:
如果數列中有重複的,比如1,3,5,5,7,此時該如何計算全排列呢?只需要去重即可。
#include <iostream>
using namespace std;
#define Swap(a,b){int temp=a; a=b; b=temp;} //交換
int data[] = {1,3,3,7};
int num = 0;
bool isEqual(int k,int m) //去重函數
{
for(int i=k; i<m; i++) //判斷a[k]到a[m-1]是否有與a[m]相同的元素,若存在,返回false
{
if(data[i] == data[m])
return false;
}
return true;
}
void Perm(int begin, int end)
{
int i;
if(begin == end) //遞歸結束,產生一個全排列(一個葉節點)
{
for(int j=0; j<3; j++) //打印全排列
{
cout<<data[j]<<" ";
}
cout<<data[3]<<endl;
num++; //統計全排列個數
}
else //沒到葉節點就遞歸下去
for(i = begin; i<=end; i++)
{
if(isEqual(begin,i))
{
Swap(data[begin],data[i]); //八當前的第i個數與後面的所有數交換位置
Perm(begin+1,end);
Swap(data[begin],data[i]); //恢復上一級,用於下一次交換
}
}
}
int main()
{
Perm(0, 3);
cout<<"全排列的個數:"<<num<<endl;
return 0;
}
打印n個數中任意m個數的全排列:
只需要將begin == end的判斷改爲 begin == m
如下:在數組中任取3個數的全排列只需:、