Python 用一些数字进行所有的二进制组合,如“?”&引用;
我必须生成给定字符串的所有可能的二进制表示,其中一些字符是“?”而其他字符是1或0 我试图做一个递归搜索,但我遇到了一些奇怪的问题,我想不出来Python 用一些数字进行所有的二进制组合,如“?”&引用;,python,recursion,binary,Python,Recursion,Binary,我必须生成给定字符串的所有可能的二进制表示,其中一些字符是“?”而其他字符是1或0 我试图做一个递归搜索,但我遇到了一些奇怪的问题,我想不出来 userInput = list(input()) anslist = [] def fill(inp): #print(inp) if inp.count("?") == 0: print(inp, "WAS ADDED") anslist.append(inp) return
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工作不正常。我似乎无法理解这一点。使用示例python代码(您可以使用等效的实现,但这很好)
用法示例:
print(generate_combinations('?01?1'))
下面是不使用内置工具的示例解决方案。这里我们使用递归,当我们在迭代输入时出现“?”时,我们将其替换为“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']
这只是使用内置的itertools.product
创建所有可能的长度为N的“01”字符串(不管字符串中有多少问号)
然后,它将其中的每一项转换为迭代器,在迭代器中,每一项一被看到就被消耗
然后我们使用re.sub
将产品替换为原始字符串,以代替问号
这是一封回复信
我在这里的评论中看到你不想使用内置的。。。所以我想没关系
如果您不想使用内置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_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))
避免使用全局或库的简单解决方案:
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
[]
>
a是一个可变类型,这意味着您只有一个列表,所有修改都是在该列表上进行的。这会导致您的第一次调用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)
使用python为all生成1和0的所有组合?如果不想使用itertools.product,可以使用嵌套循环(用于固定数量的位置)或更一般的递归。我不想使用内置工具。另外,我不知道元素的数量(=循环的数量),所以递归是一种方法。@PatrickArtner不,我是来学习的。这很好:)看到你的答案有多好,我想删除我的:D,但我很高兴听到:)
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))
> 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
[]
>
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)