我必须生成给定字符串的所有可能的二进制表示形式,其中某些字符是“?”其他为1或0。
我正在尝试进行递归搜索,但是遇到了一些我无法弄清的怪异问题。
userInput = list(input())
anslist = []
def fill(inp):
#print(inp)
if inp.count("?") == 0:
print(inp, "WAS ADDED")
anslist.append(inp)
return
for a in range(0, len(userInput)):
if inp[a] == "?":
inp[a] = 1
fill(inp)
inp[a] = 0
fill(inp)
return
print(anslist)
对于输入?01?1我应该得到: 00101、00111、10101和10111 但我明白了 10111 10101 00101已打印出来。此外,anslist无法正常运行。我似乎无法弄清楚。
答案 0 :(得分:2)
这里是不使用内置工具的示例解决方案。在这里,当发生“?”时,我们使用递归。在迭代我们的输入时,我们将其替换为“ 0”和“ 1”,并添加fill()
的结果到当前索引之后。
userInput = input()
def fill(inp):
ret = []
for idx, i in enumerate(inp):
if i == '?':
for rest in fill(inp[idx+1:]):
ret.append(inp[:idx] + '0' + rest)
ret.append(inp[:idx] + '1' + rest)
break
else:
return [inp]
return ret
print(fill(userInput))
输出
?01?1 -> ['00101', '10101', '00111', '10111']
??? -> ['000', '100', '010', '110', '001', '101', '011', '111']
答案 1 :(得分:2)
import itertools
import re
inp = "?01?1"
for combination in itertools.product("01", repeat=inp.count("?")):
i_combination = iter(combination)
print(re.sub("\?",lambda m: next(i_combination),inp))
这仅使用内置的itertools.product
来创建所有可能的长度为N的“ 01”字符串(但是字符串中有很多问号)
然后将它们中的每一个转换为一个迭代器,在该迭代器中,每项商品一被看到就被消耗掉,
然后我们使用re.sub
将产品替换为我们的原始字符串,以代替问号
这里是一个副本https://repl.it/@JoranBeasley/AssuredAncientOpengroup
我在这里的评论中看到您不想使用内置函数...所以没关系,我想
如果您不想使用内置的itertools.product ..。只需编写自己的
def my_product(s,r):
if r < 1:
yield ""
for i in range(r):
for c in s:
for partial in my_product(s,r-1):
yield c+partial
与内置迭代器相同
def my_iter(s):
for c in s:
yield c
最后,我们需要编写自己的自定义subber
def my_substitute(s,replacement):
iter_replacement = my_iter(replacement)
while s.count("?"):
s = s.replace("?",next(iter_replacement))
return s
现在我们以相同的方式将它们绑在一起
inp = "?01?1"
for combination in my_product("01", inp.count("?")):
print(my_substitute(inp,combination))
答案 2 :(得分:2)
避免使用全局或库的简单解决方案:
def fill(digits):
if not digits:
return []
first, *rest = digits
strings = fill(rest) if rest else ['']
if first == '?':
return ['0' + string for string in strings] + ['1' + string for string in strings]
return [first + string for string in strings]
userInput = input()
print(fill(userInput))
尝试拼写而不是进行最有效的数组操作,这是OP的练习。
输出
> python3 test.py
?01?1
['00101', '00111', '10101', '10111']
> python3 test.py
???
['000', '001', '010', '011', '100', '101', '110', '111']
> python3 test.py
?
['0', '1']
> python3 test.py
[]
>
答案 3 :(得分:2)
list是 mutable 类型,这意味着您只有一个列表,可以在列表上进行所有修改。这会导致您的第一个通话fill(inp)
也填写剩余的“?” inp
中的值,因此只为您提供一个结果,而第一个选择是第二个选项? (第一个?= 1:两个结果,第一个?= 0:一个结果,因为第一个?的最后一个结果仍保存在列表中)
要解决此问题,请使用list.copy()
。这样会将列表的副本传递到fill()
,从而使原始列表保持原样。
具有.copy()
和其他较小修改的完整代码:
anslist = []
def fill(inp):
if inp.count("?") == 0:
print(inp, "WAS ADDED")
anslist.append(inp)
return
for a in range(len(inp)): # range(0, x) is equivalent to range(x); try to limit global variables
if inp[a] == "?":
inp[a] = 1
fill(inp.copy()) # list is mutable
inp[a] = 0
fill(inp.copy()) # see above
return
user_input = list(input())
fill(user_input)
print(anslist)
答案 4 :(得分:1)
使用itertools.product采样python代码(您可以使用等效的实现,但这很好)
from itertools import product
def generate_combinations(inp):
count = 0
for a in range(0, len(inp)):
if inp[a] == "?": count += 1
combinations = []
for comb in product(range(2), repeat=count):
pos = 0
cinp = inp[:]
for a in range(len(cinp)):
if cinp[a] == '?':
cinp[a] = str(comb[pos])
pos += 1
combinations.append(cinp)
return combinations
用法示例:
print(generate_combinations('?01?1'))