【问题标题】:How to get an array of all possible binary numbers given a binary number of the same length如何获得所有可能组合的数量?
【发布时间】:2022-01-05 11:07:01
【问题描述】:
  • 目标:我有一个字符串通常看起来像“010”,我需要用所有可能的方式将零替换为 1,例如 ["010", "110", "111 ", "011"]

  • 问题 当我用 1 替换零时,我从左到右然后从右到左遍历字符串的字母。正如你在我做number = number[::-1] 的代码中看到的那样。现在,这种方法实际上并没有涵盖所有的可能性。

  • 我也可能需要从中间开始,或者可能使用permutation method,但不确定如何在python中应用。

    • 数学上有类似factorial of the number of places/(2)!的东西
A = '0111011110000'
B = '010101'
C = '10000010000001101'
my_list = [A,B,C]
for number in [A,B,C]:
    number = number[::-1]
    for i , n in enumerate(number):
        number = list(number)
        number[i] = '1'
        number = ''.join(number)
        if number not in my_list: my_list.append(number)


for number in [A,B,C]:
    for i , n in enumerate(number):
        number = list(number)
        number[i] = '1'
        number = ''.join(number)
        if number not in my_list: my_list.append(number)
print(len(my_list))
print(my_list)

【问题讨论】:

  • 你能告诉我们一个较短的字符串的预期输出是什么,比如010
  • @Mortz,我猜应该是["010", "110", "111", "011"]

标签: python math probability


【解决方案1】:

您可以使用分离出零,然后使用itertools.product -

from itertools import product
x = '0011'
perm_elements = [('0', '1') if digit == '0' else ('1', ) for digit in x]
print([''.join(x) for x in product(*perm_elements)])
['0011', '0111', '1011', '1111']

如果您只需要此类组合的数量,而不需要列表本身 - 那应该只是 2 ** x.count('0')

【讨论】:

  • 事实上,这个循环在处理大数字时花费了太多时间。必须有一种数学方法来计算位置数量的阶乘。我不需要这个列表我只需要组合的数量
  • @alial-karaawi,你的目标是什么?只计算可能组合的数量?
  • 应该是2 ** x.count('0'),对吧?
  • @Mortz,或1 << x.count('0'):D
  • @Mortz 如何获得没有两个连续组合的所有可能组合? '11'
【解决方案2】:

嗯,您肯定会通过固定索引组合的传统实现获得其他答案,但由于我们只使用“0”和“1”,您可以使用下一个技巧:

source = "010100100001100011"
pattern = source.replace("0", "{}")
count = source.count("0")
combinations = [pattern.format(*f"{i:0{count}b}") for i in range(1 << count)]

基本上,我们计算源中零的数量,然后迭代范围,其中 limit 是具有该设置位数量的数字,并将二进制形式的每个数字解压缩成一个模式。

如果我们也为二进制转换预定义模式应该会稍微快一些:

source = "010100100001100011"
pattern = source.replace("0", "{}")
count = source.count("0")
fmt = f"{{:0{count}b}}"
result = [pattern.format(*fmt.format(i)) for i in range(1 << count)]

更新。不清楚你需要生成所有可能的组合还是只获取数字,所以最初我提供了生成它们的代码,但如果你仔细看看我的方法,我会得到使用1 &lt;&lt; count 的所有可能组合的数量,其中count 是源字符串中'0' 字符的数量。所以如果你只需要数字,代码就是下一个:

source = "010100100001100011"
number_of_combinations = 1 << source.count("0")

或者,您也可以使用2 ** source.count("0"),但通常功率比二进制移位慢得多,所以我建议使用我最初建议的选项。

【讨论】:

  • 你能给fmt = f"{{:0{count}b}}"的文档链接吗
  • @S4eed3sm,我有点困惑,我不知道要给出什么确切的文档链接。 Format String Syntax 可能适合。
  • 只想指出&lt;&lt;是按位左移运算符
  • @Mortz,是的,有什么问题?
  • @Mortz,如果你喜欢传统数学而不是二进制,你可以用 2 ** count 替换它:D
【解决方案3】:

我们也可以对这个问题使用递归解决方案,我们遍历字符串,如果看到“0”将其更改为“1”,并在这个新字符串上开始另一个分支:

s = "010100100001100011"

def perm(s, i=0, result=[]):
    if i < len(s):
        if s[i] == "0":
            t = s[:i]+"1"+s[i+1:]
            result.append(t)
            perm(t, i+1, result)
        perm(s, i+1, result)

res = [s]
perm(s, 0, res)
print(res)

【讨论】:

    【解决方案4】:

    对于字符串中每个位置为零的位置,您可以将其替换为 1,也可以不替换。这将创建组合。因此,您可以通过根据先前的替换结果将每个“0”位置的替换添加到“1”来逐步构建字符串的结果列表:

    def zeroTo1(S):
        result = [S]                 # start with no replacement
        for i,b in enumerate(S):
            if b != '0': continue                         # only for '0' positions
            result += [r[:i]+'1'+r[i+1:] for r in result] # add replacements
        return result
    
    print(zeroTo1('010'))
    ['010', '110', '011', '111']
    

    如果您被允许使用库,则可以使用 itertools 中的产品功能直接为您组合零替换:

    from itertools import product
    def zeroTo1(S):
        return [*map("".join,product(*("01"[int(b):] for b in S)))]
    

    通过将字符串连接函数映射到其输出,将乘积函数生成的 1 和 0 元组组装成单独的字符串。

    【讨论】:

      【解决方案5】:

      根据您的目标,您可以这样做以获得预期的结果。

      A = '0111011110000'
      B = '010'
      C = '10000010000001101'
      my_list = [A, B, C]
      new_list = []
              
      for key, number in enumerate(my_list):
          for key_item, num in enumerate(number):
              item_list = [i for i in number]
              item_list[key_item] = "1"
              new_list.append(''.join(item_list))
      print(len(new_list))
      print(new_list)
      

      【讨论】:

      • 错误:it 未定义
      • 对不起,我犯了一个错误。我刚刚删除了您可以测试的有问题的行
      猜你喜欢
      • 1970-01-01
      • 2019-10-25
      • 2013-02-12
      • 1970-01-01
      • 2012-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      相关资源
      最近更新 更多