generate all n bit binary numbers in a fastest way

2019-04-11 02:34发布

How do I generate all possible combinations of n-bit strings? I need to generate all combinations of 20-bit strings in a fastest way possible. (my current implementation is done with bitwise AND and right shift operation, but I am looking for a faster technique).

I need to store the bit-strings in an array (or list) for the corresponding decimal numbers, like --

0 --> 0 0 0

1 --> 0 0 1

2 --> 0 1 0 ... etc.

any idea?

6条回答
孤傲高冷的网名
2楼-- · 2019-04-11 02:56

Just output numbers from 0 to 2^n - 1 in binary representation with exactly n digits.

查看更多
smile是对你的礼貌
3楼-- · 2019-04-11 02:58

you can do it by generate all integer number in binary representation from 0 to 2^n-1

static int[] res;
    static int n;
    static void Main(string[] args)
    {
        n = Convert.ToInt32(Console.ReadLine());
        res = new int [n];
        Generate(0);

    }

    static void Generate(int start)
    {
        if (start > n)
            return;
        if(start == n)
        {
            for(int i=0; i < start; i++)
            {
                Console.Write(res[i] + " ");
            }
            Console.WriteLine();
        }

        for(int i=0; i< 2; i++)
        {
            res[start] = i;
            Generate(start + 1);
        }
    }
查看更多
老娘就宠你
4楼-- · 2019-04-11 02:59

This solution is in Python. (versions 2.7 and 3.x should work)

>>> from pprint import pprint as pp
>>> def int2bits(n):
    return [(i, '{i:0>{n}b}'.format(i=i, n=n)) for i in range(2**n)]

>>> pp(int2bits(n=4))
[(0, '0000'),
 (1, '0001'),
 (2, '0010'),
 (3, '0011'),
 (4, '0100'),
 (5, '0101'),
 (6, '0110'),
 (7, '0111'),
 (8, '1000'),
 (9, '1001'),
 (10, '1010'),
 (11, '1011'),
 (12, '1100'),
 (13, '1101'),
 (14, '1110'),
 (15, '1111')]
>>> 

It finds the width of the maximum number and then pairs the int with the int formatted in binary with every formatted string being right padded with zero's to fill the maximum width if necessary. (The pprint stuff is just to get a neat printout for this forum and could be left out).

查看更多
Anthone
5楼-- · 2019-04-11 03:00
for (unsigned long i = 0; i < (1<<20); ++i) {
    // do something with it
}

An unsigned long is a sequence of bits.

If what you want is a string of characters '0' and '1', then you could convert i to that format each time. You might be able to get a speed-up taking advantage of the fact that consecutive numbers normally share a long initial substring. So you could do something like this:

char bitstring[21];
for (unsigned int i = 0; i < (1<<10); ++i) {
    write_bitstring10(i, bitstring);
    for (unsigned int j = 0; j < (1<<10); ++j) {
        write_bitstring10(j, bitstring + 10);
        // do something with bitstring
    }
}

I've only increased from 1 loop to 2 there, but I do a little over 50% as much converting from bits to chars as before. You could experiment with the following:

  • use even more loops
  • split the loops unevenly, maybe 15-5 instead of 10-10
  • write a function that takes a string of zeros and ones, and adds 1 to it. It's pretty easy: find the last '0', change it to a '1', and change all the '1's after it to '0'.

To fiendishly optimize write_bitstring, multiples of 4 are good because on most architectures you can blit 4 characters at a time in a word write:

To start:

assert(CHAR_BIT == 8);
uint32_t bitstring[21 / 4]; // not char array, we need to ensure alignment
((char*)bitstring)[20] = 0; // nul terminate

Function definition:

const uint32_t little_endian_lookup = {
    ('0' << 24) | ('0' << 16) | ('0' << 8) | ('0' << 0),
    ('1' << 24) | ('0' << 16) | ('0' << 8) | ('0' << 0),
    ('1' << 24) | ('1' << 16) | ('0' << 8) | ('0' << 0),
    // etc.
};
// might need big-endian version too

#define lookup little_endian_lookup // example of configuration

void write_bitstring20(unsigned long value, uint32_t *dst) {
    dst[0] = lookup[(value & 0xF0000) >> 16];
    dst[1] = lookup[(value & 0x0F000) >> 12];
    dst[2] = lookup[(value & 0x00F00) >> 8];
    dst[3] = lookup[(value & 0x000F0) >> 4];
    dst[4] = lookup[(value & 0x0000F)];
}

I haven't tested any of this: obviously you're responsible for writing a benchmark that you can use to experiment.

查看更多
倾城 Initia
6楼-- · 2019-04-11 03:07
for (i = 0; i < 1048576; i++) {
   printf('%d', i);
}

conversion of the int version i to binary string left as an exercise to the OP.

查看更多
放荡不羁爱自由
7楼-- · 2019-04-11 03:19

Python

>> n = 3
>> l = [bin(x)[2:].rjust(n, '0') for x in range(2**n)]
>> print l
['000', '001', '010', '011', '100', '101', '110', '111']
查看更多
登录 后发表回答