尽可能以最快的方式生成所有n位二进制数

时间:2012-09-07 21:51:52

标签: algorithm bitstring

如何生成所有可能的n位字符串组合?我需要以最快的方式生成20位字符串的所有组合。 (我目前的实现是通过按位AND和右移操作完成的,但我正在寻找更快的技术)。

我需要将位串存储在数组(或列表)中以获得相应的十进制数,例如 -

0 --> 0 0 0

1 --> 0 0 1

2 --> 0 1 0 ......等等。

任何想法?

6 个答案:

答案 0 :(得分:7)

的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']

答案 1 :(得分:3)

只需输出0到2 ^ n - 1的数字,二进制表示,只有n位数。

答案 2 :(得分:3)

for (unsigned long i = 0; i < (1<<20); ++i) {
    // do something with it
}

unsigned long 一系列位。

如果您想要的是一串字符'0''1',那么您每次都可以将i转换为该格式。您可以利用连续数字通常共享一个较长的初始子字符串的事实来获得加速。所以你可以这样做:

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
    }
}

我只在那里从1个循环增加到2个循环,但是我像以前一样从bit转换为chars多一点50%。您可以尝试以下内容:

  • 使用更多循环
  • 不均匀地分开循环,可能是15-5而不是10-10
  • 编写一个带有0和1字符串的函数,并将其加1。这很简单:找到最后一个'0',将其更改为'1',然后将'1'之后的所有'0'更改为write_bitstring

要非常优化assert(CHAR_BIT == 8); uint32_t bitstring[21 / 4]; // not char array, we need to ensure alignment ((char*)bitstring)[20] = 0; // nul terminate ,4的倍数是好的,因为在大多数架构中,你可以在一个单词写中一次blit 4个字符:

开始:

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)];
}

功能定义:

{{1}}

我没有测试过这些:显然你有责任编写一个你可以用来试验的基准。

答案 3 :(得分:0)

for (i = 0; i < 1048576; i++) {
   printf('%d', i);
}

将int版本i转换为二进制字符串,将其作为练习留给OP。

答案 4 :(得分:0)

此解决方案使用Python。 (版本2.7和3.x应该有效)

>>> 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')]
>>> 

找到最大数字的宽度,然后将int与以二进制格式化的int配对,每个格式化的字符串右边用零填充,以填充最大宽度(如有必要)。 (pprint的东西只是为了这个论坛得到一个整洁的打印输出,可以省略。)

答案 5 :(得分:0)

  

你可以通过从0到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);
        }
    }