I recently implemented an algorithm that has to perform checks on all subsets of some large set. A subset of an $n$-sized set can be understood as a binary string of length $n$ where bit $i$ is set if and only if the $i$-th element is in the subset. During my search for code to enumerate such bitstrings, I found the greatest page in the entire internet. If anyone can explain to me how computing the next bit permutation (the last version) works, please do.
1
s has to stay the same. It's just the smallest number that is both greater than the current one and has the same number of ones. So we calculate the smallest possible increase while maintaining the number of ones as follows: 1. Take the rightmost maximal block of1
s. Assume it has lengthn
and there arem
0
s to its right. 2. Change the0
to its left to a1
. 3. Zero out the block of1
s and 4. setn-1
bits of lowest significance to1
s. The algorithm, slightly modified using chars and more step-by-step, looks like this: Note that-~x
is just a stupid way of writingx+1
, as arithmetic negation in two's complement is equivalent to negating bit-wise and adding 1 after. Also,__builtin_ctz(cur_perm)
equalsm
. For example, saycur_perm = 0b10111000
. 1. Stepa
sets the rightmost0
s to1
:a=10111111
. 2. Stepb
flips the0
left of the rightmost block of1
s and zeroes out everything to its right:b=11000000
. 3. Stepc
consists (exactly) of all1
s to the right of the flipped bit:c=00111111
. That arem+n
1
s. 4. Stepd
shiftsc
bym+1
, therefore leaving then-1
least significant bits as1
s:d=00000011
. 5. The final step puts together the more significant bits inb
and the bits of lower significance ind
.