如何在没有itertools的情况下从数字列表中获取所有可能的值

时间:2019-04-06 12:17:46

标签: python python-3.x algorithm recursion

我想创建一种算法,该算法从数字+ - * /的列表中查找可以使用4种基本操作n创建的所有值,其中2 <= len(l) <= 6n >= 1 所有数字必须是整数。 我看过很多类似的主题,但是我不想使用itertool方法,我想了解为什么我的递归程序不起作用

我试图制作一个昂贵的递归程序,对所有可能的组合进行详尽的搜索,例如以n=len(l)开始的树和每个树的深度为n的树。

  • L起始编号列表
  • 将当前值设为C
  • M所有可能值的列表

我的代码:

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

1 个答案:

答案 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

不过效率不高。