组合算法
参考
http://dongxicheng.org/structure/permutation-combination/
实现 (01转换法)
本人在此基础上做了扩展, 不再局限于数字, 可以是任意数据
#include <cstdio> #include <vector> namespace combination { template<typename T, typename I> void make_result(std::vector<std::vector<T> >& result, const std::vector<I>& iter_result) { std::vector<T> one; for (auto i = iter_result.begin(); i != iter_result.end(); ++i) { one.push_back(**i); } result.push_back(one); } template<typename T> bool is_equals(const std::vector<T>& a, const std::vector<T>& b) { const std::size_t n = a.size(); if (n != b.size()) return false; for (std::size_t i = 0; i < n; i++) { if (a[i] != b[i]) return false; } return true; } template<typename I> int make_next(std::vector<I>& head, std::size_t r) { std::size_t i; for (i = 0; i < r - 1; i++) { if (head[i] + 1 != head[i + 1]) { break; } } head[i]++; return i; } template<typename T> void make(std::vector<std::vector<T> >& result, const std::vector<T>& args, std::size_t r) { const std::size_t nArgs = args.size(); if ((r == 0) || (nArgs < r)) return; if (nArgs == r) { result.push_back(args); return; } typedef typename std::vector<T>::const_iterator pos_t; std::vector<pos_t> head, tail; head.resize(r); tail.resize(r); for (std::size_t i = 0; i < r; i++) { head[i] = args.begin() + i; tail[i] = args.end() - (r - i); } make_result(result, head); while (!is_equals(head, tail)) { const std::size_t idx = make_next(head, r); for (std::size_t i = 0; i < idx; i++) { if (i == 0) { head[i] = args.begin(); } else { head[i] = head[i - 1] + 1; } } make_result(result, head); } return; }; } int main() { std::vector<int> args; std::vector<std::vector<int> > result; args.push_back(1); args.push_back(2); args.push_back(3); args.push_back(4); args.push_back(5); combination::make(result, args, 3); for (auto i = result.begin(); i != result.end(); ++i) { const auto& ii = *i; for (auto e = ii.begin(); e != ii.end(); ++e) { printf("%d ", *e); } printf("\n"); } return 0; }