我正在尝试提出一种有效的算法来生成所有整数i,n&我== n。例如,对于(!empty($allFields))
,n == 4
,我需要生成:
bin(n) == '0b100'
如何在Python中高效地完成这项工作?
答案 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位)的相同输出