排列组合算法之一: 01转换法_java改变后的c++版
2015-06-04 16:15
585 查看
本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标代表的数被选中,为0则没选中。
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。
// 例如求5中选3的组合:
// 1 1 1 0 0 //1,2,3
// 1 1 0 1 0 //1,2,4
// 1 0 1 1 0 //1,3,4
// 0 1 1 1 0 //2,3,4
// 1 1 0 0 1 //1,2,5
// 1 0 1 0 1 //1,3,5
// 0 1 1 0 1 //2,3,5
// 1 0 0 1 1 //1,4,5
// 0 1 0 1 1 //2,4,5
// 0 0 1 1 1 //3,4,5
java版http://blog.sina.com.cn/s/blog_605f5b4f0100vcwz.html
如下是从java改变后的c++版本:
首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。
// 例如求5中选3的组合:
// 1 1 1 0 0 //1,2,3
// 1 1 0 1 0 //1,2,4
// 1 0 1 1 0 //1,3,4
// 0 1 1 1 0 //2,3,4
// 1 1 0 0 1 //1,2,5
// 1 0 1 0 1 //1,3,5
// 0 1 1 0 1 //2,3,5
// 1 0 0 1 1 //1,4,5
// 0 1 0 1 1 //2,4,5
// 0 0 1 1 1 //3,4,5
java版http://blog.sina.com.cn/s/blog_605f5b4f0100vcwz.html
如下是从java改变后的c++版本:
////////////////////////////////////////////////////////////////////////// class ZuheAssistArray { public: typedef std::vector<std::vector<int> > TZuheResult; ZuheAssistArray(int src[], int srcLen, int m) { bool needContinue = false; // 是否是最后一种组合的标记 int n = srcLen; //C(n,m) // 生成辅助数组。首先初始化,将数组前m个元素置1,表示第一个组合为前m个数。 int * tempNum = new int (); for (int i = 0; i < m; i++) { tempNum[i] = 1; } viewArray(tempNum, n);// 打印辅助数组 std::vector<int> oneof; m_zuheCalculation.push_back(createResult(src, tempNum, n, oneof));// 打印第一个默认组合 do { int pose = 0; // 记录改变的位置 int sum = 0; // 记录改变位置 左侧 1 的个数 // 然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01” for (int i = 0; i < n - 1; i++) { if (tempNum[i] == 1 && tempNum[i + 1] == 0) { tempNum[i] = 0; tempNum[i + 1] = 1; pose = i; break; } } // 同时将其左边的所有“1”全部移动到数组的最左端。 for (int i = 0; i < pose; i++) { if (tempNum[i] == 1) sum++; } for (int i = 0; i < pose; i++) { if (i < sum) tempNum[i] = 1; else tempNum[i] = 0; } viewArray(tempNum, n);// 打印辅助数组 m_zuheCalculation.push_back(createResult(src, tempNum, n, oneof)); // 判断是否为最后一个组合:当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。 needContinue = false; for (int i = n - m; i < n; i++) { if (tempNum[i] == 0) { needContinue = true; break; } } } while (needContinue); delete [] tempNum; } static void example() { int a[] = { 1, 2, 3, 4, 5 }; // 整数数组 int m = 3; // 待取出组合的个数 ZuheAssistArray zuhe(a, 5, m); printZuheResult(zuhe.m_zuheCalculation); } // 打印组合结果 static void printZuheResult(TZuheResult zhr) { for (auto it = zhr.begin(); it != zhr.end(); it++) { for (auto itEle = it->begin(); itEle != it->end(); itEle++) { cout << *itEle << " "; } cout << std::endl; } } public: TZuheResult m_zuheCalculation; private: // 打印int数组的方法 void viewArray(int array[], int arrayLen) { #if 0 cout << "生成的辅助数组为:"; for (int i = 0; i < arrayLen; i++) { cout << array[i]; } cout << endl; #endif } // 根据辅助数组和原始数组生成 结果数组 std::vector<int> & createResult(const int src[], const int assist[], const int srcLen, std::vector<int> &dst) { dst.clear(); for (int i = 0; i < srcLen; i++) { if (assist[i] == 1) { dst.push_back(src[i]); } } return dst; } };
相关文章推荐
- C++静态库与动态库
- C++中如何表示2进制,8进制、16进制变量
- C语言运算符的优先级
- C++四种强制类型转换运算符
- 双向链表的一个C++实现
- c++ containers
- 【C语言/算法之 01 背包】基础版
- c/c++字符串传递
- c++函数
- VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径
- C++语言编写静态链接库及其使用
- C/C++中各种类型int、long、double、char表示范围(最大最小值)
- C/C++中sizeof与strlen的区别
- C++11 lambda 表达式解析
- C++ 学习
- C语言编写静态链接库及其使用
- C++9.3.6 容器 访问元素
- eclipse C++开发环境下怎样修改Author
- C++9.3.5容器大小的操作
- C++_运算符重载 总结