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

来源:互联网 发布:名言警句短的网络 编辑:程序博客网 时间:2024/06/05 22:51
研究了递归生成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)




0 0
原创粉丝点击