以下是一个全排列的泛型算法的简单实现;
我用它生成测试序列可以用于一些代码的测试;
顺便研究一下泛型算法;
下面的实现还是较初级, 还有待改进;
#pragma warning(disable: 4530)
#pragma warning(disable: 4786)
#include <cassert>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <exception>
using namespace std;
//阶乘, 不检测溢出
unsigned __int64 _tFactorial(unsigned __int64 N)
{
unsigned __int64 r = 1;
for(unsigned __int64 i = 2; i <= N; i ++)
r *= i;
return r;
}
//全排列, 不检测重复
template<typename T, typename Array>
void arrange(T * first, T *last, Array matrix, int row = 0, int col = 0)
{
if(first >= last)
return;
int N = last - first;
if(N == 1) //递归终止
{
matrix[row][col] = *first;
return;
}
int line_N = _tFactorial(N - 1);
T *temp = new T[N - 1], *cp;
for(int i = 0, j; i < N; i ++)
{
for(j = 0; j < line_N; j ++)
matrix[i * line_N + j + row][col] = *(first + i);
for(cp = temp, j = 0; j < N; j ++)
if(j != i)
*cp ++ = *(first + j);
arrange<T>(temp, temp + N - 1, matrix, row + i * line_N, col + 1);
}
delete[] temp;
}
int main(int argc, char *argv[])
{
try
{
int i, j;
char c[5] = "1234"; //待排列数据
char rc[24][4]; //保存结果
string str[3] = {"the", "if", "else"};
string rstr[6][3];
arrange<char>(c, c + 4, rc);
for(i = 0; i < 24; i ++)
{
for(j = 0; j < 4; j ++ )
cout << rc[i][j] << ',';
cout << endl;
}
arrange<string>(str, str + 3, rstr);
for(i = 0; i < 6; i ++)
{
for(j = 0; j < 3; j ++ )
cout << rstr[i][j] << ',';
cout << endl;
}
//STL容器
char vc[] = "ABCD";
vector<char> vec(vc, vc + 4);
vector<vector<char> > rvec; //不能使用容器作返回参数
arrange<char>(vec.begin(), vec.end(), rc);
for(i = 0; i < 24; i ++)
{
for(j = 0; j < 4; j ++ )
cout << rc[i][j] << ',';
cout << endl;
}
}
catch(exception &e)
{
cout << e.what() << endl;
}
return 0;
}
---------- 结果----------
1,2,3,4,
1,2,4,3,
1,3,2,4,
1,3,4,2,
1,4,2,3,
1,4,3,2,
2,1,3,4,
2,1,4,3,
2,3,1,4,
2,3,4,1,
2,4,1,3,
2,4,3,1,
3,1,2,4,
3,1,4,2,
3,2,1,4,
3,2,4,1,
3,4,1,2,
3,4,2,1,
4,1,2,3,
4,1,3,2,
4,2,1,3,
4,2,3,1,
4,3,1,2,
4,3,2,1,
the,if,else,
the,else,if,
if,the,else,
if,else,the,
else,the,if,
else,if,the,
A,B,C,D,
A,B,D,C,
A,C,B,D,
A,C,D,B,
A,D,B,C,
A,D,C,B,
B,A,C,D,
B,A,D,C,
B,C,A,D,
B,C,D,A,
B,D,A,C,
B,D,C,A,
C,A,B,D,
C,A,D,B,
C,B,A,D,
C,B,D,A,
C,D,A,B,
C,D,B,A,
D,A,B,C,
D,A,C,B,
D,B,A,C,
D,B,C,A,
D,C,A,B,
D,C,B,A,