On Sat, 17 Dec 2011 08:05:20 -0800 (PST), Andrew Tomazos
<
and...@tomazos.com> wrote:
>I want to loop over every number from 0 to (2^m-1) inclusive whos
>binary representation contains exactly n bits.
>
>ie
>
>for (int i = 0; i < (1<<m); i++)
>{
> int bits = 0;
> for (int j = 0; j < m; j++)
> if (i & (1 << j))
> bits++;
> if (bits == n)
> do_something_with(i);
>}
>
>Clearly this is terribly inefficient. I'm sure there is a much faster
>way (perhaps by enumerating with mod/div somehow each continous
>sequence of 1s and continuous sequence of 0'x) but I can't seem to see
>it.
A recursive approach comes to mind. Approximately:
#include <stdio.h>
void n_of_m_bits_r(int nbr, int b, int m, int n)
// nbr = candidate number
// b = current number of one bits in nbr
// m = number of additional bits to add to nbr
// n = desired number of one bits
{
if (m==0)
{ // Gotten to the end
if (b == n)
printf("%i\n", nbr); // Finished with correct # of bits
return;
}
if ((n-b)>m)
return; // no longer enough bits left to get to n
// Add zero bit case (IOW nbr was "abcd", process "abcd0"):
n_of_m_bits_r((nbr<<1), b, (m-1), n);
// Add one bit case (IOW nbr was "abcd", process "abcd1"):
if ((b+1) <= n)
n_of_m_bits_r(((nbr<<1)+1), (b+1), (m-1), n);
}
void n_of_m_bits(int m, int n)
{
n_of_m_bits_r(0, 0, m, n);
}
int main()
{
n_of_m_bits(7, 2); // list all seven bit numbers w/two bits set
return 0;
}
(minimally tested, etc.)
This lengthens the number by a single bit each recursion, but short
circuits the process when the accumulated number of bits becomes too
high, or the number of remaining bits becomes too low to reach the
required total.