N种有序二进制掩码排列

N permutations of binary mask with order

提问人:Rudziankoŭ 提问时间:8/15/2022 最后编辑:DaveRudziankoŭ 更新时间:8/15/2022 访问量:151

问:

我有“理想”的二进制掩码,例如: ,我需要获得它最相似的变体。在相似性意义上,更改左位更可取。因此,如果 n == 5,那么我将得到以下变体:0000n

1000
0100
0010
0001
1100

我想过回溯算法,但是我该如何维持秩序呢?哪种算法最适合此情况?

Python 算法 与语言无关

评论

0赞 CtrlZ 8/15/2022
这些值的数据类型是什么?它们是字符串吗?
0赞 Rudziankoŭ 8/15/2022
是的,它们是字符串
0赞 Jim Mischel 8/15/2022
按 4 位和 5 位的顺序生成和排列掩码。然后想想你用来安排它们的规则。你能想出一种方法在代码中表达这些规则吗?
1赞 Dave 8/15/2022
哪个更可取:1001 还是 0110?
0赞 Kelly Bundy 8/16/2022
@GuyCoder 这与此有什么关系?

答:

2赞 Thierry Lathuille 8/15/2022 #1

您可以利用以下事实,即按您要查找的明确顺序返回组合。itertools.combinations

我们可以生成 0、1、2 ...“1”位必须位于 4 个位置,并相应地创建字符串。

产生口罩的发电机可能是:

def masks(ideal):
    size = len(ideal)
    positions = list(range(size))  # will be for example [0, 1, 2, 3]

    # we start with 0 flipped bit, then one, up to all
    for nb_flipped in range(0, size+1):
        # we get all combinations of positions where to flip that many bits
        for flipped_positions in combinations(positions, r=nb_flipped):
            out = list(ideal)
            # and we flip the bits at these positions
            for pos in flipped_positions:
                out[pos] =  '1' if out[pos] == '0' else '0'
            yield ''.join(out)

你可以像这样使用它:

for m in masks('0000'):
    print(m)
    
# 0000
# 1000
# 0100
# 0010
# 0001
# 1100
# 1010
# 1001
# 0110
# 0101
# 0011
# 1110
# 1101
# 1011
# 0111 
# 1111 
    

如果你想要第一个列表,你可以使用如下函数:n

def list_of_masks(ideal, n):
    return list(islice(masks(ideal), n))
    

在您的样品理想面膜上,这给出了:

print(list_of_masks('0101', 6))

# ['0101', '1101', '0001', '0111', '0100', '1001']

评论

0赞 Rudziankoŭ 8/15/2022
谢谢你的回答!看起来很漂亮,但我有点迷失在 3 个嵌套循环中)我有几个问题:1)什么是时间复杂度?2)如果我的“理想”面具是我需要得到->。所提供的方法是否适用于此?0101[1101, 0001, 0111, 0100, 1001]
0赞 Thierry Lathuille 8/15/2022
我相应地更新了答案。时间复杂度只是 O(n),只生成你想要的 n 个掩码。