C++的STL库中实现了全排列算法next_permutation,在头文件algorithm中。
自己根据全排列算法写了一个模板全排列的类
为了省事使用std::vector与std::sort
#ifndef PERMUTATION_H
#define PERMUTATION_H
#include <utility>
#include <vector>
#include <algorithm>
#include <functional>
/*全排列类*/
template<class T>
class Permutation
{
public:
//加入全排列元素
inline void Push(vector<T>const T &data);
//将序列排序到初始状态,调用std::sort
inline void Sort();
//与上面无参数的函数功能相同,参数为调用std::sort需要用到的比较方法
inline void Sort(std::function<bool(const T&,const T&)> Less);
//重置全排列的初始状态
inline void Reset();
//执行全排列并对每个序列执行Func,返回全排列个数
inline unsigned long long DoPermutation(std::function<void(std::vector<T> &)> Func);
//清空该对象
inline void Clear();
private:
typedef std::pair<T,bool> Data;
std::vector<Data> datas;
std::vector<T> pm;
unsigned long long num;
std::function<void(std::vector<T>&)> Func;
void GetPermutation(unsigned pos);
};
template<class T>
void Permutation<T>::Push(const T &data)
{
datas.push_back({data,false});
pm.push_back(T());
}
template<class T>
void Permutation<T>::Sort()
{
sort(datas.begin(),datas.end());
Reset();
}
template<class T>
void Permutation<T>::Sort(std::function<bool(const T&,const T&)> Cmp)
{
sort(datas.begin(),datas.end(),Cmp);
Reset();
}
template<class T>
void Permutation<T>::Reset()
{
for(auto &i:datas)
i.second=false;
num=0;
}
template<class T>
unsigned long long Permutation<T>::DoPermutation(std::function<void(std::vector<T>&)> Func)
{
Reset();
this->Func=Func;
GetPermutation(0);
return num;
}
template<class T>
void Permutation<T>::Clear()
{
datas.clear();
pm.clear();
num=0;
}
template<class T>
void Permutation<T>::GetPermutation(unsigned pos)
{
if(pos==pm.size())
{
Func(pm);
++num;
return;
}
for(unsigned i=0;i<datas.size();++i)
{
if(datas[i].second)
continue;
datas[i].second=true;
pm[pos]=datas[i].first;
GetPermutation(pos+1);
datas[i].second=false;
}
}
#endif
测试代码:
#include <iostream>
using namespace std;
int main()
{
Permutation<int> per;
int num;
for(int i=1;i<5;++i)
per.Push(i);
num=per.DoPermutation(
[](std::vector<int> &a)
{
for(auto i:a)
cout<<i;
cout<<'\n';
});
cout<<"共有"<<num<<"个排列"<<endl;
return 0;
}
输出结果:
1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321
共有24个排列