码迷,mamicode.com
首页 > 其他好文 > 详细

输出所有排列组合

时间:2015-06-28 12:28:34      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

本文预先假定您对递归的思想有较深入的认识,所以没有写太多细碎的注释,至于为什么要那个样子递归调用,相信独立看懂您会大有收获的。本文更重要的是列出基本思想,并且通过两个算法的对比揭示排列和组合的内在联系,有疑问的朋友们可以留言跟我交流

 

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!