给定n个不同的数,要求生成这n个数的全排列!
解法1:递归思想,首先选定第一个数(有n种不同的选择方式),然后对剩下的n-1个数进行全排列;根据此步骤,对剩下n-1数的全排列进行递归。
void Permutation(vector<int>& ivec, int level)
{
if( level == ivec.size() )
{
copy(ivec.begin(), ivec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return;
}
for(int i = level; i < ivec.size(); ++i)
{
swap(ivec[level], ivec[i]);
Permutation(ivec, level + 1);
swap(ivec[level], ivec[i]);
}
}
解法2:枚举思想,想象有n个位置,每一个位置可放置一个数。对每一个位置枚举各个数字。
void Permutation(vector<int>& ivec, vector<int> per,
vector<bool>& ok, int level)
{
if( level == ivec.size() )
{
copy(per.begin(), per.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return ;
}
for(int i = 0; i < ivec.size(); ++i)
{
if( !ok[i] )
{
ok[i] = true;
per[level] = ivec[i];
Permutation(ivec, per, ok, level + 1);
ok[i] = false;
}
}
}
解法3:根据初始排列,依次生成下一个排列。如 1 2 3 -> 1 3 2 -> 2 1 3... ...
int Find(vector<int>& ivec, int i)
{
while( i > 0 && ivec[i-1] > ivec[i] )
--i;
return i;
}
int Bsearch(vector<int>& ivec, int beg, int val)
{
int low = beg, high = ivec.size() - 1;
while( low <= high )
{
int mid = low + (high - low)/2;
if(ivec[mid] > val )
low = mid + 1;
else high = mid - 1;
}// stop when ivec[low] <= val or ivec[high] > val
return high;
}
void Permutation(vector<int>& ivec)
{
while(true)
{
copy(ivec.begin(), ivec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
int i = ivec.size() - 1;
int j = Find(ivec, i);
if( !j ) break;
int k = Bsearch(ivec, j, ivec[j-1]);
swap(ivec[j-1], ivec[k]);
sort(ivec.begin() + j, ivec.end());
};
}
完整代码+测试:
#include <bits/stdc++.h>
using namespace std;
class Incr {
public:
Incr(int init = 0):beg(init){
};
int operator()() {
return beg++;
};
private:
int beg;
};
void Permutation(vector<int>& ivec, int level)
{
if( level == ivec.size() )
{
copy(ivec.begin(), ivec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return;
}
for(int i = level; i < ivec.size(); ++i)
{
swap(ivec[level], ivec[i]);
Permutation(ivec, level + 1);
swap(ivec[level], ivec[i]);
}
}
void Permutation(vector<int>& ivec, vector<int> per,
vector<bool>& ok, int level)
{
if( level == ivec.size() )
{
copy(per.begin(), per.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return ;
}
for(int i = 0; i < ivec.size(); ++i)
{
if( !ok[i] )
{
ok[i] = true;
per[level] = ivec[i];
Permutation(ivec, per, ok, level + 1);
ok[i] = false;
}
}
}
int Find(vector<int>& ivec, int i)
{
while( i > 0 && ivec[i-1] > ivec[i] )
--i;
return i;
}
int Bsearch(vector<int>& ivec, int beg, int val)
{
int low = beg, high = ivec.size() - 1;
while( low <= high )
{
int mid = low + (high - low)/2;
if(ivec[mid] > val )
low = mid + 1;
else high = mid - 1;
}// stop when ivec[low] <= val or ivec[high] > val
return high;
}
void Permutation(vector<int>& ivec)
{
while(true)
{
copy(ivec.begin(), ivec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
int i = ivec.size() - 1;
int j = Find(ivec, i);
if( !j ) break;
int k = Bsearch(ivec, j, ivec[j-1]);
swap(ivec[j-1], ivec[k]);
sort(ivec.begin() + j, ivec.end());
};
}
void Work()
{
vector<int> ivec(4);
generate(ivec.begin(), ivec.end(), Incr(1));
Permutation(ivec);
//Permutation(ivec, 0);
//vector<bool> ok(3, false);
//Permutation(ivec, vector<int>(3), ok, 0);
}
int main()
{
Work();
return 0;
}