您的位置:首页 > 其它

基于格雷码生成算法的n选m排列算法

2017-03-13 16:15 190 查看
研究了递归生成n选m排列算法时,发现递归算法中有较多的重复计算。重复计算源自获取长排列时,对于每一个长排列的子集——短排列,都是重新计算得到的,没有对已经生成的短排列进行利用。通过研究格雷码生成算法(http://blog.csdn.net/aitazhixin/article/details/61915679),发现采用类似格雷码的插入算法,能避免这种重复获取短排列的问题。

插入算法的基本思想为:

1,首先生成单元素排列为:1;2;3;……;n;

2,在已生成的短排列上每个排列后面,插入1~n,对于短排列上已有的元素,则不重复插入;
3,重复步骤2将得到最终的m排列。

代码如下:

#include <iostream>
#include <vector>
#include <time.h>

using namespace std;

void FullPermutation(int m, int n);

int main()
{
int m, n;

cout << "Input number of count: ";
cin >> n;

cout << "Input permutation number: ";
cin >> m;
clock_t startTime = clock();
FullPermutation(m, n);
clock_t endTime = clock();

cout << "Processing Time: " << (endTime - startTime) << endl;

return 0;
}

void FullPermutation(int m, int n)
{
vector<vector<int>> vec;

if ((m < 1) && (n < 1))
return;

if (m > n)
{
FullPermutation(n, n);
return;
}

vec.resize(n);

for (int pIdx = 1; pIdx <= n; pIdx++)
{
vector<int> pvec;
pvec.push_back(pIdx);
vec[pIdx - 1].assign(pvec.begin(), pvec.end());
}

for (int pIdx = 2; pIdx <= m; pIdx++)
{
vector<vector<int>> tmpVec;
int vSize = vec.size();
int newVecIdx = 0;
tmpVec.assign(vec.begin(), vec.end());
vec.resize(vSize * (n - pIdx + 1));

for (int vIdx = 0; vIdx < vSize; vIdx++)
{
for (int tIdx = 1; tIdx <= n; tIdx++)
{
if (tmpVec[vIdx].end() == find(tmpVec[vIdx].begin(), tmpVec[vIdx].end(), tIdx))
{
vector<int> tVec;
vec[newVecIdx].assign(tmpVec[vIdx].begin(), tmpVec[vIdx].end());
vec[newVecIdx].push_back(tIdx);
newVecIdx++;
}
}
}
}

int aSize = vec.size();
//for (int aIdx = 0; aIdx < aSize; aIdx++)
//{
// vector<int>::iterator tmpIter = vec[aIdx].begin();
// for (; tmpIter != vec[aIdx].end(); tmpIter++)
// {
// cout << *tmpIter << "\t";
// }

// cout << endl;
//}

cout << "Number of Permutation: " << aSize << endl;

return;

}

运行效率比较:
本节算法



原算法(http://blog.csdn.net/aitazhixin/article/details/61414329)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  递归算法 算法