📅  最后修改于: 2023-12-03 15:39:41.431000             🧑  作者: Mango
给定一个正整数N,打印所有长度为N的二进制数中,所有前缀中1的个数大于0的数。
对于一个长度为N的二进制数,它的前缀可以用前缀和的方式求解。我们只需要统计出每个位置前面有多少个1,然后判断是否大于0即可。
具体的,假设当前二进制数为$x$,$pre_i$表示$x$的前$i$个位置中,1的个数。则$pre_i$的求法如下:
$pre_i = pre_{i-1} + [x_i = 1], i \in [1, N]$
其中$[x_i = 1]$为指示函数,当$x_i = 1$时为1,否则为0。
判断$x$是否符合条件,只需要判断$pre_i > 0$是否对于$1 \le i \le N$成立即可。
def print_special_binary_numbers(N):
"""
打印所有长度为N的二进制数中,所有前缀中1的个数大于0的数
"""
for i in range(1, 1 << N):
pre_ones = 0
is_special = True
for j in range(N):
if i & (1 << j):
pre_ones += 1
if pre_ones <= 0:
is_special = False
break
if is_special:
print(bin(i)[2:].zfill(N))
代码中,我们首先枚举二进制数$i$的值。对于每个$i$,我们从低到高地逐位考虑,同时记录当前位置之前1的个数。如果在所有的位置上,前缀中1的个数都大于0,就输出当前二进制数。
值得注意的是,为了输出时左边补0对齐,我们在最后使用了字符串的zfill
函数。
N = 1
1
N = 2
10
11
N = 3
110
111
N = 4
1110
1111