如何生成所有整数i,n& i == n(保持位长)

时间:2015-08-02 02:16:34

标签: python bit-manipulation

我正在尝试提出一种有效的算法来生成所有整数i,n&我== n。例如,对于(!empty($allFields))n == 4,我需要生成:

bin(n) == '0b100'

如何在Python中高效地完成这项工作?

5 个答案:

答案 0 :(得分:1)

这有效:

def get_matches(n, bin_n):
    # It would be easier to pass number and numbits,
    # but this was the problem definition, so we'll
    # make sure they match...
    assert n == int(bin_n, 0), (n, bin_n)

    numbits = len(bin_n) - bin_n.index('b') - 1
    fmt = "{0:d} ('0b{0:0%db}')" % numbits
    for i in range(2 ** numbits):
        if i & n == n:
            print(fmt.format(i))

get_matches(4, '0b100')

结果:

4 ('0b100')
5 ('0b101')
6 ('0b110')
7 ('0b111')

答案 1 :(得分:1)

我会用简单的列表生成器启动

n = 7; u = 256
for i in [x for x in range(n,u) if x & n == n]
    print(i)

您可以根据具体目的调整上限范围(256)和按位检查值(7)。使用n的起始值是因为匹配该条件的最小数字本身是n

如果您发现列表太大([...]实际上在内存中生成临时列表),您可以使用生成器而不是列表。它懒洋洋地计算每个值,因此您不必存储如此庞大的列表。这只是使用(...)而不是[...]

的问题
n = 7; u = 4294967296
for i in (x for x in range(n,u) if x & n == n):
    print(i)

对于16位(正如您在注释中指定的那样),这些内置方法应该足够快。在我的机器上,输出所有16位数字(使用n = 0)只需不到半秒的CPU时间,如果你对它们什么都不做的话,则输出更加令人印象深刻的1/25秒。

答案 2 :(得分:1)

这是一个递归算法,它可以处理任意整数,而不仅仅是2的幂:

def matching_bitfields(n):
    if n == 0:
        yield 0
    else:
        has_free_bit = n & 1 == 0
        for m in matching_bitfields(n >> 1):
            m <<= 1
            if has_free_bit:
                yield m
            yield m | 1

def print_matching_bitfields(n):
    for x in matching_bitfields(n):
        print '%r (%r)' % (x, '0b{0:b}'.format(x))

print_matching_bitfields(4)

这将打印:

4 ('0b100')
5 ('0b101')
6 ('0b110')
7 ('0b111')

答案 3 :(得分:1)

您只需增加i并确保n中的位保持设置即可获得此结果:

def next(n):
    i = n
    while (i >> 1) < n:
        yield i
        i = (i + 1) | n

我假设您想要在i需要比n更多的位时退出迭代。

答案 4 :(得分:0)

n = 4
b = n.bit_length()  # => 3
start = 1 << (b-1)  # => 1 << 2 => 4
for i in range(start, start*2):
    print(i, bin(i))

输出:

4 0b100
5 0b101
6 0b110
7 0b111

这将产生5,6,7(所有3位)的相同输出