#include <utility> #include <cstddef> #include <vector> using std::size_t; template<typename Lambda> void for_each_multiset_combo( std::vector<size_t> const& counts, Lambda&& lambda ) { if (counts.empty()) { lambda(counts); return; } std::vector<size_t> indexes; indexes.reserve( counts.size() ); while(true) { while (indexes.size() < counts.size()) { indexes.push_back(0); } lambda( indexes ); indexes.back()++; while (indexes.back() > counts[indexes.size()-1]) { indexes.pop_back(); if (indexes.empty()) return; // finished indexes.back()++; } } } #include <iostream> int main() { std::vector<size_t> multiset = {3, 2, 1, 1}; size_t counter = 0; for_each_multiset_combo( multiset, [&]( std::vector<size_t> const& counts ){ std::cout << counter << ": ["; for(auto it = counts.begin(); it != counts.end(); ++it) { if (it != counts.begin()) { std::cout << ", "; } std::cout << *it; } std::cout << "]\n"; ++counter; }); }
Standard input is empty
0: [0, 0, 0, 0] 1: [0, 0, 0, 1] 2: [0, 0, 1, 0] 3: [0, 0, 1, 1] 4: [0, 1, 0, 0] 5: [0, 1, 0, 1] 6: [0, 1, 1, 0] 7: [0, 1, 1, 1] 8: [0, 2, 0, 0] 9: [0, 2, 0, 1] 10: [0, 2, 1, 0] 11: [0, 2, 1, 1] 12: [1, 0, 0, 0] 13: [1, 0, 0, 1] 14: [1, 0, 1, 0] 15: [1, 0, 1, 1] 16: [1, 1, 0, 0] 17: [1, 1, 0, 1] 18: [1, 1, 1, 0] 19: [1, 1, 1, 1] 20: [1, 2, 0, 0] 21: [1, 2, 0, 1] 22: [1, 2, 1, 0] 23: [1, 2, 1, 1] 24: [2, 0, 0, 0] 25: [2, 0, 0, 1] 26: [2, 0, 1, 0] 27: [2, 0, 1, 1] 28: [2, 1, 0, 0] 29: [2, 1, 0, 1] 30: [2, 1, 1, 0] 31: [2, 1, 1, 1] 32: [2, 2, 0, 0] 33: [2, 2, 0, 1] 34: [2, 2, 1, 0] 35: [2, 2, 1, 1] 36: [3, 0, 0, 0] 37: [3, 0, 0, 1] 38: [3, 0, 1, 0] 39: [3, 0, 1, 1] 40: [3, 1, 0, 0] 41: [3, 1, 0, 1] 42: [3, 1, 1, 0] 43: [3, 1, 1, 1] 44: [3, 2, 0, 0] 45: [3, 2, 0, 1] 46: [3, 2, 1, 0] 47: [3, 2, 1, 1]