【暴力】枚举生成全排列

Posted on 2018-03-07 17:40  som_nico  阅读(1139)  评论(0编辑  收藏  举报

(刘汝佳紫皮书)

生成1~n的排列。

对于一个长度为n数组长度的数组={0,1,2,3,..., n-1}。要想枚举它的所有的长度为n的全排列出来。

有两种选择:一个是直接枚举, 另外一个是使用递归来构造。

1.直接枚举

n 大的时候就要写 n-1个for循环

2.递归

 

递归函数: print_permutation(int n, int *A, int cur)

递归使用需要有判定界限,定义一个数组A,往A[]里面放我们需要排列的元素。 cur为当前要确定的元素位置。我们的判定界限则是: 当 n=cur 时 return 。 

代码如下。

 1 void print_permutation(int n, int* A, int cur)
 2 {
 3     if(n == cur)//排列到n个长度后输出
 4     {
 5         for(int i = 0; i < n; i++)
 6             cout << A[i];
 7         cout << endl;
 8         return;
 9     }
10     else
11     {
12         for(int i = 0; i < n; i++)
13         {
14             int ok = 1;
15             for(int j = 0; j < cur; j++)
16             //判断i是不是已经使用过了
17                 if(A[j] == i)
18                     ok = 0;
19             if(ok)
20             {
21                 A[cur] = i;
22                 print_permutation(n, A, cur + 1);
23             }
24         }
25     }
26 }

 

 

生成可重集的排列

详细描述见刘汝佳紫皮书185页。

因为重集,所以只需要在上面代码上加重集元素出现次数的比较即可。

 1 #include <iostream>  
 2 #include <algorithm>  
 3 using namespace std;  
 4 
 5 void printPermutation(int n, int* p, int cur, int* arr)        //n是元素个数,p是初始元素集合,cur是当前位置,arr是目前已经排列的部分
 6 {
 7     int i, j;
 8     if (cur == n)
 9     {
10         for (i = 0; i < n; i++)
11         {
12             printf("%d ", arr[i]);
13         }
14         printf("\n");
15     }
16     else
17     {
18         for (i = 0; i < n; i++)
19         {
20             if (i == 0 || p[i] != p[i-1])    //只需要检查第一个元素,以及与前一个元素不相同的元素即可,保证不重复
21             {
22                 int c1 = 0, c2 = 0;
23                 for (j = 0; j < cur; j++)    //已经排列的元素中p[i]出现的次数
24                 {
25                     if (arr[j] == p[i])
26                     {
27                         c1++;
28                     }
29                 }
30                 for (j = 0; j < n; j++)        //全部元素中p[i]出现的次数
31                 {
32                     if (p[i] == p[j])
33                     {
34                         c2++;
35                     }
36                 }
37                 if (c1 < c2)    //保证不遗漏
38                 {
39                     arr[cur] = p[i];
40                     printPermutation(n, p, cur+1, arr);
41                 }
42             }
43         }
44     }
45 }
46 
47 int main()  
48 {  
49     int p[5] = {4, 1, 1, 4, 1};
50     sort(p, p+5);    //排序
51     int arr[5] = {0};
52     printPermutation(5, p, 0, arr);
53     return 0;
54 }