I am studying for an interview and I stumbled upon this question online under the "Math" category.
Generate power set of given set:
int A[] = {1,2,3,4,5};
int N = 5;
int Total = 1 << N;
for ( int i = 0; i < Total; i++ ) {
for ( int j = 0; j < N; j++) {
if ( (i >> j) & 1 )
cout << A[j];
}
cout <<endl;
}
Please I do not want an explicit answer. I just want clarifications and hints on how to approach this problem.
I checked power set algorithm on google and I still do not understand how to address this problem.
Also, could someone reiterate what the question is asking for.
Thank you.
Power set of a set A is the set of all of the subsets of A.
Not the most friendly definition in the world, but an example will help :
Eg. for {1, 2}, the subsets are : {}, {1}, {2}, {1, 2}
Thus, the power set is {{}, {1}, {2}, {1, 2}}
To generate the power set, observe how you create a subset : you go to each element one by one, and then either retain it or ignore it.
Let this decision be indicated by a bit (1/0).
Thus, to generate {1}, you will pick 1 and drop 2 (10).
On similar lines, you can write a bit vector for all the subsets :
{} -> 00
{1} -> 10
{2} -> 01
{1,2} -> 11
To reiterate : A subset if formed by including some or all of the elements of the original set. Thus, to create a subset, you go to each element, and then decide whether to keep it or drop it. This means that for each element, you have 2 decisions. Thus, for a set, you can end up with 2^N different decisions, corresponding to 2^N different subsets.
See if you can pick it up from here.
Create a power-set of: {"A", "B", "C"}.
Pseudo-code:
val set = {"A", "B", "C"}
val sets = {}
for item in set:
for set in sets:
sets.add(set + item)
sets.add({item})
sets.add({})
Algorithm explanation:
1) Initialise sets to an empty set: {}.
2) Iterate over each item in {"A", "B", "C"}
3) Iterate over each set in your sets.
3.1) Create a new set which is a copy of set.
3.2) Append the item to the new set.
3.3) Append the new set to sets.
4) Add the item to your sets.
4) Iteration is complete. Add the empty set to your resultSets.
Walkthrough:
Let's look at the contents of sets after each iteration:
Iteration 1, item = "A":
sets = {{"A"}}
Iteration 2, item = "B":
sets = {{"A"}, {"A", "B"}, {"B"}}
Iteration 3, item = "C":
sets = {{"A"}, {"A", "B"}, {"B"}, {"A", "C"}, {"A", "B", "C"}, {"B", "C"}, {"C"}}
Iteration complete, add empty set:
sets = {{"A"}, {"A", "B"}, {"B"}, {"A", "C"}, {"A", "B", "C"}, {"B", "C"}, {"C"}, {}}
The size of the sets is 2^|set| = 2^3 = 8 which is correct.
Example implementation in Java:
public static <T> List<List<T>> powerSet(List<T> input) {
List<List<T>> sets = new ArrayList<>();
for (T element : input) {
for (ListIterator<List<T>> setsIterator = sets.listIterator(); setsIterator.hasNext(); ) {
List<T> newSet = new ArrayList<>(setsIterator.next());
newSet.add(element);
setsIterator.add(newSet);
}
sets.add(new ArrayList<>(Arrays.asList(element)));
}
sets.add(new ArrayList<>());
return sets;
}
Input: [A, B, C]
Output: [[A], [A, C], [A, B], [A, B, C], [B], [B, C], [C], []]
Power set is just set of all subsets for given set. It includes all subsets (with empty set). It's well-known that there are 2N elements in this set, where N is count of elements in original set.
To build power set, following thing can be used:
Create a loop, which iterates all integers from 0 till 2N-1
Proceed to binary representation for each integer
Each binary representation is a set of N bits (for lesser numbers, add leading zeros). Each bit corresponds, if the certain set member is included in current subset.
Example, 3 numbers: a, b, c
number binary subset
0 000 {}
1 001 {c}
2 010 {b}
3 011 {b,c}
4 100 {a}
5 101 {a,c}
6 110 {a,b}
7 111 {a,b,c}
Well, you need to generate all subsets. For a set of size n, there are
2n subsets.
One way would be to iterate over the numbers from 0 to 2n - 1
and convert each to a list of binary digits, where 0 means exclude
that element and 1 means include it.
Another way would be with recursion, divide and conquer.
Generating all combination of a set (By including or not an item).
explain by example:
3 items in a set (or list). The possible subset will be:
000
100
010
001
110
101
011
111
The result is 2^(number of elements in the set).
As such we can generate all combinations of N items (with python) as follows:
def powerSet(items):
N = len(items)
for i in range(2**N):
comb=[]
for j in range(N):
if (i >> j) % 2 == 1:
comb.append(items[j])
yield comb
for x in powerSet([1,2,3]):
print (x)
You Get Something Like This by Implementing the top rated Answer.
def printPowerSet(set,set_size):
# set_size of power set of a set
# with set_size n is (2**n -1)
pow_set_size = (int) (math.pow(2, set_size));
counter = 0;
j = 0;
# Run from counter 000..0 to 111..1
for counter in range(0, pow_set_size):
for j in range(0, set_size):
# Check if jth bit in the
# counter is set If set then
# pront jth element from set
if((counter & (1 << j)) > 0):
print(set[j], end = "");
print("");
C# Solution
Time Complexity and Space Complexity: O(n*2^n)
public class Powerset
{
/*
P[1,2,3] = [[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
*/
public List<List<int>> PowersetSoln(List<int> array)
{
/*
We will start with an empty subset
loop through the number in the array
loop through subset generated till and add the number to each subsets
*/
var subsets = new List<List<int>>();
subsets.Add(new List<int>());
for (int i = 0; i < array.Count; i++)
{
int subsetLen = subsets.Count;
for (int innerSubset = 0; innerSubset < subsetLen; innerSubset++)
{
var newSubset = new List<int>(subsets[innerSubset]);
newSubset.Add(array[i]);
subsets.Add(newSubset);
}
}
return subsets;
}
}
Sample Java Code:
void printPowerSetHelper(String s, String r) {
if (s.length() > 0) {
printPowerSetHelper(s.substring(1), r + s.charAt(0));
printPowerSetHelper(s.substring(1), r);
}
if (r.length() > 0) System.out.println(r);
}
void printPowerSet(String s) {
printPowerSetHelper(s,"");
}
Related
I'm not aware nor could I find an algorithm to generate combinations of k items (i.e. k-subsets) lexicographically. I do know algorithms to generate combinations of n choose k, but they don't generate the k-subsets lexicographically.
Can somebody help me out with this or point me in the right direction?
The following algorithm will generate all combinations of elements of a set:
procedure all_combinations(S)
if length(S) == 0
return {}
else
all_comb = {}
x = first element of S
Sx = S-{x}
for each C in all_combinations(Sx)
all_comb += C
all_comb += {x} ∪ C
return all_comb
For the set {1,2,3}, this algorithm does…
all_combinations({2,3})
all_combinations({3})
all_combinations({}), which returns {}
all_combinations({3}) returns {{}, {3}}
all_combinations({2,3}) returns {{}, {2}, {3}, {2,3}}
all_combinations({1,2,3}) returns {{}, {1}, {2}, {1,2}, {3}, {1,3}, {2,3}, {1,2,3}}
This algorithm basically uses some simple rules to determine the next token in the combination: assume a set N of size n and an unfinished combination C that is so far filled with c < k elements (searched combinations have length = k). Now C[c + 1] must lie in the range between (both inclusive) N[indexOf(C[c]) + 1] (each element must be higher than the previous to ensure order) and N[k - c + 1] (there are k - (c - 1) free spaces for remaining elements, which must aswell be higher than their previous element). Using this we can generate the combinations pretty easy recursively:
define combinationsLex(T[] set , int k)
sort(set)
//initialize the combinations with their first element
for int i in [0 , length(set) - k]
int c_init[k]
c_init[0] = set[i]
combinationsLexRec(set , c_init , 1)
//set is the alphabet from which the combinations are created, c is the current
//incomplete combination and at is the position in c at which the next element will be inserted
define combinationsLexRec(T[] set , int[] c , int at)
if at == length(c)
//do whatever you want with the combination
for int i in [c[at] + 1 , length(set) - c[at]]
int[] nc = copy(c)
nc[at] = set[i]
combinationsLexRec(set , nc , at + 1)
Notes:
this implementation assumes 0-based arrayindices
the result is only ordered lexicographically if the input is ordered aswell
I wrote recursive backtracking algorithm for finding all subsets of a given set.
void backtracke(int* a, int k, int n)
{
if (k == n)
{
for(int i = 1; i <=k; ++i)
{
if (a[i] == true)
{
std::cout << i << " ";
}
}
std::cout << std::endl;
return;
}
bool c[2];
c[0] = false;
c[1] = true;
++k;
for(int i = 0; i < 2; ++i)
{
a[k] = c[i];
backtracke(a, k, n);
a[k] = INT_MAX;
}
}
now we have to write the same algorithm but in an iterative form, how to do it ?
You can use the binary counter approach. Any unique binary string of length n represents a unique subset of a set of n elements. If you start with 0 and end with 2^n-1, you cover all possible subsets. The counter can be easily implemented in an iterative manner.
The code in Java:
public static void printAllSubsets(int[] arr) {
byte[] counter = new byte[arr.length];
while (true) {
// Print combination
for (int i = 0; i < counter.length; i++) {
if (counter[i] != 0)
System.out.print(arr[i] + " ");
}
System.out.println();
// Increment counter
int i = 0;
while (i < counter.length && counter[i] == 1)
counter[i++] = 0;
if (i == counter.length)
break;
counter[i] = 1;
}
}
Note that in Java one can use BitSet, which makes the code really shorter, but I used a byte array to illustrate the process better.
There are a few ways to write an iterative algorithm for this problem. The most commonly suggested would be to:
Count (i.e. a simply for-loop) from 0 to 2numberOfElements - 1
If we look at the variable used above for counting in binary, the digit at each position could be thought of a flag indicating whether or not the element at the corresponding index in the set should be included in this subset. Simply loop over each bit (by taking the remainder by 2, then dividing by 2), including the corresponding elements in our output.
Example:
Input: {1,2,3,4,5}.
We'd start counting at 0, which is 00000 in binary, which means no flags are set, so no elements are included (this would obviously be skipped if you don't want the empty subset) - output {}.
Then 1 = 00001, indicating that only the last element would be included - output {5}.
Then 2 = 00010, indicating that only the second last element would be included - output {4}.
Then 3 = 00011, indicating that the last two elements would be included - output {4,5}.
And so on, all the way up to 31 = 11111, indicating that all the elements would be included - output {1,2,3,4,5}.
* Actually code-wise, it would be simpler to turn this on its head - output {1} for 00001, considering that the first remainder by 2 will then correspond to the flag of the 0th element, the second remainder, the 1st element, etc., but the above is simpler for illustrative purposes.
More generally, any recursive algorithm could be changed to an iterative one as follows:
Create a loop consisting of parts (think switch-statement), with each part consisting of the code between any two recursive calls in your function
Create a stack where each element contains each necessary local variable in the function, and an indication of which part we're busy with
The loop would pop elements from the stack, executing the appropriate section of code
Each recursive call would be replaced by first adding it's own state to the stack, and then the called state
Replace return with appropriate break statements
A little Python implementation of George's algorithm. Perhaps it will help someone.
def subsets(S):
l = len(S)
for x in range(2**l):
yield {s for i,s in enumerate(S) if ((x / 2**i) % 2) // 1 == 1}
Basically what you want is P(S) = S_0 U S_1 U ... U S_n where S_i is a set of all sets contained by taking i elements from S. In other words if S= {a, b, c} then S_0 = {{}}, S_1 = {{a},{b},{c}}, S_2 = {{a, b}, {a, c}, {b, c}} and S_3 = {a, b, c}.
The algorithm we have so far is
set P(set S) {
PS = {}
for i in [0..|S|]
PS = PS U Combination(S, i)
return PS
}
We know that |S_i| = nCi where |S| = n. So basically we know that we will be looping nCi times. You may use this information to optimize the algorithm later on. To generate combinations of size i the algorithm that I present is as follows:
Suppose S = {a, b, c} then you can map 0 to a, 1 to b and 2 to c. And perumtations to these are (if i=2) 0-0, 0-1, 0-2, 1-0, 1-1, 1-2, 2-0, 2-1, 2-2. To check if a sequence is a combination you check if the numbers are all unique and that if you permute the digits the sequence doesn't appear elsewhere, this will filter the above sequence to just 0-1, 0-2 and 1-2 which are later mapped back to {a,b},{a,c},{b,c}. How to generate the long sequence above you can follow this algorithm
set Combination(set S, integer l) {
CS = {}
for x in [0..2^l] {
n = {}
for i in [0..l] {
n = n U {floor(x / |S|^i) mod |S|} // get the i-th digit in x base |S|
}
CS = CS U {S[n]}
}
return filter(CS) // filtering described above
}
I have a list and I need to find and extract all numbers in close proximity to a new list.
for example I have a list:
1,5,10,8,11,14,15,11,14,1,4,7,5,9
so if I want to extract all numbers that are close by 3(only 3, the gap must be 3, so 11,14 is correct, 11,13 is not.) near each other how can I design this without hard-coding the whole thing?
the result should look like:
8,11,14,11,14,1,4,7
This doesn't look too hard ,but I'm kind stuck, all I can come up with is a loop that checks n+1 member of the loop if it's more than n by 3 and include the n+1 member in a new list, however I don't know how to include the n member without making it appear on the new list twice if there is a string of needed numbers.
any ideas?
Just loop through the list, checking the next and previous element, and save the current one if it differs by 3 from either one. In Python, that's
>>> l = [1,5,10,8,11,14,15,11,14,1,4,7,5,9]
>>> # pad with infinities to ease the final loop
>>> l = [float('-inf')] + l + [float('inf')]
>>> [x for i, x in enumerate(l[1:-1], 1)
... if 3 in (abs(x - l[i-1]), abs(x - l[i+1]))]
[8, 11, 14, 11, 14, 1, 4, 7]
In Matlab
list = [1,5,10,8,11,14,15,11,14,1,4,7,5,9]
then
list(or([diff([0 diff(list)==3]) 0],[0 diff(list)==3]))
returns
8 11 14 11 14 1 4 7
For those who don't understand Matlab diff(list) returns the first (forward) differences of the elements in list. The expression [0 diff(list)] pads the first differences with a leading 0 to make the result the same length as the original list. The rest should be obvious.
In a nutshell: take forward differences and backward differences, select the elements where either difference is 3.
A simple C++ code below:
assuming ar is the array of the initial integers and mark is a boolean array
for(int i=1;i<N;i++){
if(ar[i]-ar[i-1]==3){
mark[i]=1;
mark[i-1]=1;
}
}
Now to print the interesting numbers,
for(int i=0;i<N;i++){
if(mark[i]==1)cout<<ar[i]<<" ";
}
The idea behind the implementation is, we mark a number as interesting if the difference from it to its previous one is 3 or if the difference between it and its next number is 3.
that's a single loop:
public List<int> CloseByN(int n, List<int> oldL)
{
bool first = true;
int last = 0;
bool isLstAdded = false;
List<int> newL = new List<int>();
foreach(int curr in oldL)
{
if(first)
{
first = false;
last = curr;
continue;
}
if(curr - last == n)
{
if(isLstAdded == false)
{
newL.Add(last);
isLstAdded = true;
}
newL.Add(curr);
}
else
{
isLstAdded = false;
}
last = curr;
}
return newL;
}
tested on your input and got your output
And a Haskell version:
f g xs = dropWhile (null . drop 1) $ foldr comb [[last xs]] (init xs) where
comb a bbs#(b:bs)
| abs (a - head b) == g = (a:head bbs) : bs
| otherwise =
if null (drop 1 b) then [a] : bs else [a] : bbs
Output:
*Main> f 3 [5,10,8,11,14,15,11,14,1,4,7,5,9]
[[8,11,14],[11,14],[1,4,7]]
*Main> f 5 [5,10,8,11,14,15,11,14,1,4,7,5,9]
[[5,10]]
I know this was talked over a lot here, but I am struggling with this problem.
We have a set of numbers, e.g [3, 1, 1, 2, 2, 1], and we need to break it into two subsets, so the each sum is equal or difference is minimal.
I've seen wikipedia entry, this page (problem 7) and a blog entry.
But every algorithm listed is giving only YES/NO result and I really don't understand how to use them to print out two subsets (e.g S1 = {5, 4} and S2 = {5, 3, 3}). What am I missing here?
The pseudo-polynomial algorithm is designed to provide an answer to the decision problem, not the optimization problem. However, note that the last row in the table of booleans in the example indicates that the current set is capable of summing up to N/2.
In the last row, take the first column where the boolean value is true. You can then check what the actual value of the set in the given column is. If the sets summed value is N/2 you have found the first set of the partition. Otherwise you have to check which set is capable of being the difference to N/2. You can use the same approach as above, this time for the difference d.
This will be O(2^N). No Dynamic Programming used here. You can print result1, result2 and difference after execution of the function. I hope this helps.
vector<int> p1,p2;
vector<int> result1,result2;
vector<int> array={12,323,432,4,55,223,45,67,332,78,334,23,5,98,34,67,4,3,86,99,78,1};
void partition(unsigned int i,long &diffsofar, long sum1,long sum2)
{
if(i==array.size())
{
long diff= abs(sum1 - sum2);
if(diffsofar > diff)
{
result1 = p1;
result2 = p2;
diffsofar = diff;
}
return;
}
p1.push_back(array[i]);
partition(i+1,diffsofar,sum1+array[i],sum2);
p1.pop_back();
p2.push_back(array[i]);
partition(i+1,diffsofar,sum1,sum2+array[i]);
p2.pop_back();
return;
}
I faced this same problem recently, and I posted a question about it (here: Variant of Knapsack). The difference in my case is that the resulting subsets must be the same size (if the original set has an even number of elements). In order to assure that, I added a few lines to #Sandesh Kobal answer;
void partition(unsigned int i,long &diffsofar, long sum1,long sum2)
{
int maxsize = (array.size()+1)/2;
if(p1.size()>maxsize)
return;
if(p2.size()>maxsize)
return;
if(i==array.size())
{
...
Also, after both calls to partition, I added if(diffsofar==0) return;. If we already found an optimal solution, it makes no sense to keep searching...
All the articles I've seen take a dynamic programming approach. Do we really need one?
Suppose the array given is arr
Use the following algorithm :
Sort the array in descending order
Create two empty arrays, a = [] and b = []
sum_a = sum_b = 0
for x in arr:
if sum_a > sum_b:
b.append(x)
sum_b += x
else:
a.append(x)
sum_a += x
The absolute difference between sum_a and sum_b would be the minimum possible difference between the two subsets.
Consider arr = [3,1,1,2,2,1]
Sorting the array : arr = [3,2,2,1,1,1]
a = [], b = []
a = [3], b = []
a = [3], b = [2]
a = [3], b = [2,2]
a = [3,1], b = [2,2]
a = [3,1,1], b = [2,2]
a = [3,1,1], b = [2,2,1]
sa = 5, sb = 5
Minimum difference : 5 - 5 = 0
I am trying to figure out an efficient algorithm to take a list of items and generate all unique subsets that result from splitting the list into exactly 2 sublists. I'm sure there is a general purpose way to do this, but I'm interested in a specific case. My list will be sorted, and there can be duplicate items.
Some examples:
Input
{1,2,3}
Output
{{1},{2,3}}
{{2},{1,3}}
{{3},{1,2}}
Input
{1,2,3,4}
Output
{{1},{2,3,4}}
{{2},{1,3,4}}
{{3},{1,2,4}}
{{4},{1,2,3}}
{{1,2},{3,4}}
{{1,3},{2,4}}
{{1,4},{2,3}}
Input
{1,2,2,3}
Output
{{1},{2,2,3}}
{{2},{1,2,3}}
{{3},{1,2,2}}
{{1,2},{2,3}}
{{1,3},{2,2}}
I can do this on paper, but I'm struggling to figure out a simple way to do it programmatically. I'm only looking for a quick pseudocode description of how to do this, not any specific code examples.
Any help is appreciated. Thanks.
If you were generating all subsets you would end up generating 2n subsets for a list of length n. A common way to do this is to iterate through all the numbers i from 0 to 2n-1 and use the bits that are set in i to determine which items are in the ith subset. This works because any item either is or is not present in any particular subset, so by iterating through all the combinations of n bits you iterate through the 2n subsets.
For example, to generate the subsets of (1, 2, 3) you would iterate through the numbers 0 to 7:
0 = 000b → ()
1 = 001b → (1)
2 = 010b → (2)
3 = 011b → (1, 2)
4 = 100b → (3)
5 = 101b → (1, 3)
6 = 110b → (2, 3)
7 = 111b → (1, 2, 3)
In your problem you can generate each subset and its complement to get your pair of mutually exclusive subsets. Each pair would be repeated when you do this so you only need to iterate up to 2n-1 - 1 and then stop.
1 = 001b → (1) + (2, 3)
2 = 010b → (2) + (1, 3)
3 = 011b → (1, 2) + (3)
To deal with duplicate items you could generate subsets of list indices instead of subsets of list items. Like with the list (1, 2, 2, 3) generate subsets of the list (0, 1, 2, 3) instead and then use those numbers as indices into the (1, 2, 2, 3) list. Add a level of indirection, basically.
Here's some Python code putting this all together.
#!/usr/bin/env python
def split_subsets(items):
subsets = set()
for n in xrange(1, 2 ** len(items) / 2):
# Use ith index if ith bit of n is set.
l_indices = [i for i in xrange(0, len(items)) if n & (1 << i) != 0]
# Use the indices NOT present in l_indices.
r_indices = [i for i in xrange(0, len(items)) if i not in l_indices]
# Get the items corresponding to the indices above.
l = tuple(items[i] for i in l_indices)
r = tuple(items[i] for i in r_indices)
# Swap l and r if they are reversed.
if (len(l), l) > (len(r), r):
l, r = r, l
subsets.add((l, r))
# Sort the subset pairs so the left items are in ascending order.
return sorted(subsets, key = lambda (l, r): (len(l), l))
for l, r in split_subsets([1, 2, 2, 3]):
print l, r
Output:
(1,) (2, 2, 3)
(2,) (1, 2, 3)
(3,) (1, 2, 2)
(1, 2) (2, 3)
(1, 3) (2, 2)
The following C++ function does exactly what you need, but the order differs from the one in examples:
// input contains all input number with duplicates allowed
void generate(std::vector<int> input) {
typedef std::map<int,int> Map;
std::map<int,int> mp;
for (size_t i = 0; i < input.size(); ++i) {
mp[input[i]]++;
}
std::vector<int> numbers;
std::vector<int> mult;
for (Map::iterator it = mp.begin(); it != mp.end(); ++it) {
numbers.push_back(it->first);
mult.push_back(it->second);
}
std::vector<int> cur(mult.size());
for (;;) {
size_t i = 0;
while (i < cur.size() && cur[i] == mult[i]) cur[i++] = 0;
if (i == cur.size()) break;
cur[i]++;
std::vector<int> list1, list2;
for (size_t i = 0; i < cur.size(); ++i) {
list1.insert(list1.end(), cur[i], numbers[i]);
list2.insert(list2.end(), mult[i] - cur[i], numbers[i]);
}
if (list1.size() == 0 || list2.size() == 0) continue;
if (list1 > list2) continue;
std::cout << "{{";
for (size_t i = 0; i < list1.size(); ++i) {
if (i > 0) std::cout << ",";
std::cout << list1[i];
}
std::cout << "},{";
for (size_t i = 0; i < list2.size(); ++i) {
if (i > 0) std::cout << ",";
std::cout << list2[i];
}
std::cout << "}\n";
}
}
A bit of Erlang code, the problem is that it generates duplicates when you have duplicate elements, so the result list still needs to be filtered...
do([E,F]) -> [{[E], [F]}];
do([H|T]) -> lists:flatten([{[H], T}] ++
[[{[H|L1],L2},{L1, [H|L2]}] || {L1,L2} <- all(T)]).
filtered(L) ->
lists:usort([case length(L1) < length(L2) of true -> {L1,L2};
false -> {L2,L1} end
|| {L1,L2} <- do(L)]).
in pseudocode this means that:
for a two long list {E,F} the result is {{E},{F}}
for longer lists take the first element H and the rest of the list T and return
{{H},{T}} (the first element as a single element list, and the remaining list)
also run the algorithm recursively for T, and for each {L1,L2} element in the resulting list return {{H,L1},{L2}} and {{L1},{H,L2}}
My suggestion is...
First, count how many of each value you have, possibly in a hashtable. Then calculate the total number of combinations to consider - the product of the counts.
Iterate through that number of combinations.
At each combination, copy your loop count (as x), then start an inner loop through your hashtable items.
For each hashtable item, use (x modulo count) as your number of instances of the hashtable key in the first list. Divide x by the count before repeating the inner loop.
If you are worried that the number of combinations might overflow your integer type, the issue is avoidable. Use an array with each item (one for every hashmap key) starting from zero, and 'count' through the combinations treating each array item as a digit (so the whole array represents the combination number), but with each 'digit' having a different base (the corresponding count). That is, to 'increment' the array, first increment item 0. If it overflows (becomes equal to its count), set it to zero and increment the next array item. Repeat the overflow checks until If overflows continue past the end of the array, you have finished.
I think sergdev is using a very similar approach to this second one, but using std::map rather than a hashtable (std::unordered_map should work). A hashtable should be faster for large numbers of items, but won't give you the values in any particular order. The ordering for each loop through the keys in a hashtable should be consistent, though, unless you add/remove keys.