我想创建一种算法,该算法从数字+ - * /
的列表中查找可以使用4种基本操作n
创建的所有值,其中2 <= len(l) <= 6
和n >= 1
所有数字必须是整数。
我看过很多类似的主题,但是我不想使用itertool
方法,我想了解为什么我的递归程序不起作用
我试图制作一个昂贵的递归程序,对所有可能的组合进行详尽的搜索,例如以n=len(l)
开始的树和每个树的深度为n
的树。
我的代码:
def result(L,C,M):
if len(L)>0:
for i in range(len(L)) :
a=L[i]
if C>=a:
l=deepcopy(L)
l.remove(a)
m=[] # new current values
#+
m.append(C+a)
# * 1 is useless
if C !=1 or a !=1:
m.append(C*a)
# must be integer
if C%a==0 and a<=C: # a can't be ==0
m.append(C//a)
#0 is useless
if C!=a:
m.append(C-a)
for r in m: #update all values possible
if r not in M:
M.append(r)
for r in m: # call the fucntion again with new current values,and updated list of remaining number
result(l,r,M)
def values_possible(L) :
m=[]
for i in L:
l=deepcopy(L)
l.remove(i)
result(l,i,m)
m.sort()
return m
对于没有重复编号的小列表,我的算法似乎可以运行,但是对于[1,1,2,2,4,5]
这样的列表,它会丢失一些值。
它返回:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, 100, 101,
102, 104, 105, 110, 112, 115, 116, 118, 119, 120, 121, 122, 124, 125, 128, 130,
140, 160]
但它错过了93,108,114,117,123,126,132,135,150,180
。
答案 0 :(得分:0)
让我们举一个更简单的示例:[1, 1, 2, 2]
。
您的算法找不到的数字之一是9 = (1 + 2) * (1 + 2)
。
您的算法根本无法进行此计算,因为它始终处理“当前”值C
。您可以从C = 1 + 2
开始,但是找不到下一个1 + 2
,因为它必须单独构造。
因此,您的递归必须至少将某种划分成两组,找到所有答案,然后将它们组合起来。
类似的事情可能起作用:
def partitions(L):
if not L:
yield ([], [])
else:
for l, r in partitions(L[1:]):
yield [L[0]] + l, r
yield l, [L[0]] + r
def values_possible(L):
if len(L) == 1:
return L
results = set()
for a, b in partitions(L):
if not a or not b:
continue
for va in values_possible(a):
for vb in values_possible(b):
results.add(va + vb)
results.add(va * vb)
if va > vb:
results.add(va - vb)
if va % vb == 0:
results.add(va // vb)
return results
不过效率不高。