在Python3中生成具有给定单词的不同前缀的n位的所有可能组合

时间:2018-02-26 16:32:00

标签: python python-3.x encoding restrictions

我遇到了以下问题。给定一个单词(二进制单词)我想生成长度为n的所有组合,并且给定的单词不能是任何组合的前缀。

例如,n = 300这个词我希望生成:

010
011
100
101
110
111

有没有pythonic方式来做到这一点?

编辑:对不起,我正在尝试修改此标准伪代码

combinations:
if depth = 0 return result
for i in start..size
    out+=combinations(depth-1, i+1, result)
return out

我无法弄清楚如何添加不以给定单词开头的限制。通过" pythonic"我的意思是像理解列表,或美丽的单行:D

1 个答案:

答案 0 :(得分:0)

You can do all the work in a one-liner, but it takes a bit of setup. This takes advantage of the fact that you basically want all the binary numbers within a range of 0 to 2**n, except if their leftmost bits represent a particular binary number. Note that in general you will be keeping most of the numbers in the range (all but 1/2**len(word)), so it's reasonably efficient just to generate all the numbers and then filter out the ones you don't want.

word = '00'
word_int = int(word, base=2)
m = len(word)
n = 3
results = ['{0:b}'.format(num).zfill(n) for num in range(2**n) if num >> (n-m) != word_int]
print('\n'.join(results))
# 010
# 011
# 100
# 101
# 110
# 111

You can eliminate some of the setup, but the one-liner gets harder to read:

word = '00'
n = 3
[
    num 
    for num in ('{0:b}'.format(p).zfill(n) for p in range(2**n)) 
    if not num.startswith(word)
]

Or you can use itertools.product

word = '00'
n = 3
[
    num 
    for num in (''.join(p) for p in itertools.product('01', repeat=n)) 
    if not num.startswith(word)
]