排列组合是高中数学里我们学过的知识,不过那时候我们计算的是满足某一条件的排列组合的总数,也就是说,我们求的是一个数值。而今天的问题是:通过完成一个程序,列出某个排列组合的所有可能情况。
问题:
- 如何生成由$n$个数字组成的所有$k$位数?
- 如何生成$n$个数中选择$k$个数的所有排列$A_n^k$ ?
- 如何生成$n$个数中选择$k$个数的所有组合$C_n^k$ ?
关键点:
- 填每一位时,把选择的数字存到一个结果数组中,填完所有位之后一起输出。
- 填完一位之后要选择下一种情况时,需要把当前元素从结果数组ary[]中弹出。
- 排列,组合不能重复使用元素,因此用过的要做个标记(-1)。
- 组合与顺序无关,默认采用递增的顺序。
代码:
求$N_5^4, A_5^4$和$C_5^4$:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <iostream> #include <vector> using namespace std; vector<int> ary; vector<int> eles = {1, 2, 3, 4, 5}; int n_ = eles.size(); int k_ = 4; void N(int k) { if (k == 0) { for (int e : ary) { cout << e << " "; } cout << endl; } else { for (int e : eles) { ary.push_back(e); N(k - 1); ary.pop_back(); } } } void A(int k) { if (k == 0) { for (int e : ary) { cout << e << " "; } cout << endl; } else { for (int i = 0; i < n_; i++) { if (eles[i] > 0) { ary.push_back(eles[i]); int temp = eles[i]; eles[i] = -1; A(k - 1); eles[i] = temp; ary.pop_back(); } } } } void C(int k) { if (k == 0) { for (int e : ary) { cout << e << " "; } cout << endl; } else { int last_used_idx = 0; for (last_used_idx = n_ - 1; last_used_idx >= 0 && eles[last_used_idx] > 0; last_used_idx--); if (k == n_ - last_used_idx) { for (int i = 0; i < n_; i++) { if (eles[i] > 0) { ary.push_back(eles[i]); } } } else { for (int j = last_used_idx + 1; j <= n_ - k; j++) { ary.push_back(eles[j]); int temp = eles[j]; eles[j] = -1; C(k - 1); eles[j] = temp; ary.pop_back(); } } } } int main() { cout << "The numbers are: " << endl; N(k_); cout << "The arrangement is: " << endl; A(k_); cout << "The combination is: " << endl; C(k_); }
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| The numbers are: 1 1 1 1 1 1 1 2 1 1 1 3 1 1 1 4 1 1 1 5 1 1 2 1 ... ... 5 5 5 1 5 5 5 2 5 5 5 3 5 5 5 4 5 5 5 5 The arrangement is: 1 2 3 4 1 2 3 5 1 2 4 3 1 2 4 5 ... ... 5 4 2 1 5 4 2 3 5 4 3 1 5 4 3 2 The combination is: 1 2 3 4 1 2 3 5 1 2 4 5 1 3 4 5 2 3 4 5
|