按照字典序生成的排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void nextPermutation(vector<int>& lastPermutation) { size_t j = lastPermutation.size() - 2; size_t k = lastPermutation.size() - 1; size_t r = lastPermutation.size() - 1; size_t s; while (lastPermutation[j] > lastPermutation[j + 1]) { --j; } while (lastPermutation[j] > lastPermutation[k]) { --k; } swap(lastPermutation[j], lastPermutation[k]); s = j + 1; while (r > s) { --r; ++s; } sort(lastPermutation.begin() + j + 1, lastPermutation.end()); }
|
实现全排列可以简单的执行次生成下一个排列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| size_t fact(size_t t) { if (t == 0 || t == 1) return 1; return t * fact(t - 1); }
vector<vector<int>> fullPermutation(vector<int> initial) { vector<vector<int>> res; sort(initial.begin(), initial.end()); res.push_back(initial); for (size_t t = 1; t < fact(initial.size()); ++t) { res.push_back(res[res.size() - 1]); nextPermutation(res[res.size() - 1]); } return res; }
|
生成组合
- 对于一个大小为的集合,该问题可以转变为一个求所有长度为的
Bit String
的问题,即通过表示选择一个元素,而则不选择它
- 更加简洁的方法生成所有
Bit String
是直接通过余二倒取生成二进制串,遍历所有二进制的范围为
此为生成下一个最大Bit String
的算法,此算法本质是计算一个二进制加一的结果。
1 2 3 4 5
| void nextBitString(string &lastBitString) { auto c = lastBitString.rbegin(); while (c != lastBitString.rend() && *c == '1') (*c = '0', ++c); *c = '1'; }
|
类似的,这里给出生成所有Bit String
的算法
1 2 3 4 5 6 7 8 9
| vector<string> allBitString(size_t length) { vector<string> res; res.push_back(string(length, '0')); for (size_t i = 1; i < (1 << length); ++i) { res.push_back(res[res.size() - 1]); nextBitString(res[res.size() - 1]); } return res; }
|
按照字典序生成集合的组合
此算法为按照字典序生成下一个组合
1 2 3 4 5 6 7 8 9 10 11 12 13
| void nextCombination(vector<size_t> &lastCombination, size_t n) { auto i = lastCombination.size() - 1; while (lastCombination[i] == (n - lastCombination.size() + i + 1)) { if (i != 0) --i; else break; } ++lastCombination[i]; for (auto j = i + 1; j < lastCombination.size(); j++) { lastCombination[j] = lastCombination[i] + j - i; } }
|
类似的,给出求出所有组合的算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| long long fact(size_t t) { if (t == 0 || t == 1) return 1; return t * fact(t - 1); }
long long C(size_t n, size_t r) { return fact(n) / fact(n - r) / fact(r); }
vector<vector<size_t>> fullCombination(vector<size_t> initial, size_t n) { vector<vector<size_t>> res; sort(initial.begin(), initial.end()); res.push_back(initial); for (long long i = 1; i < C(n, initial.size()); i++) { res.push_back(res[res.size() - 1]); nextCombination(res[res.size() - 1], n); } return res; }
|