标签:
本文预先假定您对递归的思想有较深入的认识,所以没有写太多细碎的注释,至于为什么要那个样子递归调用,相信独立看懂您会大有收获的。本文更重要的是列出基本思想,并且通过两个算法的对比揭示排列和组合的内在联系,有疑问的朋友们可以留言跟我交流
a1,a2,...,an。求输出这n个数中任取m个的排列及组合序列。
1 #include <iostream> 2 3 struct Element 4 { 5 int num; 6 bool bUsed;//标记num是否已被选取 7 }; 8 9 //本算法的基本思想是: 10 //从给定的数字集中搜索需要的m个数字 11 //每次先“随机”取一个数字(数学书上对于排列的理解,第一个数字有n种取法,第二个n-1中。。。),然后从剩下的数字集中寻找剩下的m-1个数字 12 //每次找满m个数字就输出结果 13 14 //arr是给定数组a1,a2,...,an 15 //n是arr的长度 16 //m是要取的数字个数 17 //m1是当前还需要搜索的数字个数 18 //destArr是一个长度为m的一维数组,存储每次搜索到的结果 19 //permutationCount是所有满足条件的排列数 20 21 void Permutation( Element* arr, int n, int m, int m1, int* destArr, int& permutationCount) 22 { 23 //一次搜索完毕,输出结果 24 if (m1 <= 0) 25 { 26 for (int j = 0; j < m; ++j) 27 std::cout << destArr[j] << " "; 28 std::cout << std::endl; 29 ++permutationCount; 30 return; 31 } 32 33 for (int i = 0; i < n; ++i) 34 { 35 if (!arr[i].bUsed) 36 { 37 //先取一个未被使用的数 38 //当前这个数的取值范围就是那些目前未被使用的数字们 39 destArr[m-m1] = arr[i].num; 40 //该数标记为已使用 41 arr[i].bUsed = true; 42 43 //递归搜索剩下的m1-1个数字 44 if (m1 >= 1) 45 Permutation(arr, n, m, m1 - 1, destArr, permutationCount); 46 47 //还原标记状态,进行下一轮搜索 48 arr[i].bUsed = false; 49 } 50 } 51 } 52 53 //知道怎么求排列了,求组合那不是简单得很! 54 //我们知道排列和组合的区别在于组合是无序的,排列是有序的 55 //比如 (1,2,4)和(2,1,4)是两个排列,却是同一个组合 56 //我们只要在上边的排列算法中加一个限定条件就可以求组合了 57 //这里我们限定每次只向数组索引增加的方向搜索,这样就能够消除重复项了 58 59 //preIndex是上一个数字的索引 60 void Combinition( Element* arr, int n, int m, int m1,int preIndex, int* destArr, int& combinitioCount) 61 { 62 if (m1 <= 0) 63 { 64 for (int j = 0; j < m; ++j) 65 std::cout << destArr[j] << " "; 66 std::cout << std::endl; 67 ++combinitioCount; 68 return; 69 } 70 71 for (int i = 0; i < n; ++i) 72 { 73 //通过增加条件 i > preIndex 限定搜索方向! 74 if (!arr[i].bUsed && i > preIndex) 75 { 76 destArr[m-m1] = arr[i].num; 77 arr[i].bUsed = true; 78 if (m1 >= 1) 79 Combinition(arr, n, m, m1 - 1, i, destArr, combinitioCount); 80 arr[i].bUsed = false; 81 } 82 } 83 } 84 85 int main(int argc, char *argv[]) 86 { 87 Element arr[8]; 88 for (int i = 0; i < 8; ++i) 89 { 90 arr[i].num = i + 1; 91 arr[i].bUsed = false; 92 } 93 int destArr[8]; 94 int count = 0; 95 Permutation(arr, 8, 3, 3, destArr, count); 96 97 Combinition(arr, 8, 3, 3, -1, destArr, count); 98 std::cout << "total count: " << count << std::endl; 99 }
标签:
原文地址:http://www.cnblogs.com/luobende/p/4605238.html