So the challenge is to design an algorithm that PRINTS the subsets of a given set n
.
Let's set n equal:
n = {a,b,c}
On this stack overflow article there is an answer from @Piva that solves this problem using the fact that "Each number from 0 to 2^n gives a unique subset in its binary representation"
I have written a Javascript version of @Piva's code, it works well. I understand most of it except one line:
if(((i>>j) & 1) === 1)
I think I understand this line of code is shifting i bits right, adding j zeros to the beginning of i's binary representation. I also understand the bit wise & is comparing i >>j to 1 and seeing if the first bit is on from the output i >>.
But I don't understand how this operation identifies unique binary representations and why the if(((i>>j) & 1) === 1)
being true means we have a unique subset of a given n
.
Here is my Javascript version:
function SubsetBuilder(set) {
this.set = set;
}
SubsetBuilder.prototype.getSubsets = function () {
var self = this;
if (!self.set)
return null;
//recursive way, do next
var getSubsetsAll = function (originalSet) {
if (!originalSet) {
return;
}
}
var n = this.set.length;
for(var i = 0; i < (1<<n); i++) {
var subset = [];
for (var j = 0; j < n; j++) {
console.log('i:' + i + ", binary: " + i.toString(2));
console.log('j:' + j + ", binary: " + j.toString(2));
console.log('(i >> j):');
console.log((i >> j));
console.log('((i>>j) & 1):');
console.log(((i >> j) & 1));
if(((i>>j) & 1) === 1){ // bit j is on
subset.push(this.set[j]);
}
console.log('-------------------');
}
console.log(subset);
console.log('-------------------');
}
}
var set = ['a', 'b', 'c'];
var obj = new SubsetBuilder(set);
obj.getSubsets();
if(((i>>j) & 1) === 1)
checks if the j-th bit of i is set.To understand how this works, consider the number 5 in binary 101b.
>>
is just a shift (or equivalently, division by 2n) and& 1
masks out all but the least significant bit.So once wen understand how the bit-extraction works, we need to understand why bit-extraction is equivalent to subset inclusion:
Here's how we map from binary numbers 0-7 to subsets of {A,B,C}
And clearly we have listed all subsets.
Hopefully you can now see why the test for the j-th bit of i is equivalent to the inclusion of the j-th object into the ith subset.