简体   繁体   English

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

[英]How to get all values possible from a list of number without itertools

I want to create an algorithm that find all values that can be created with the 4 basic operations + - * / from a list of number n , where 2 <= len(l) <= 6 and n >= 1 All numbers must be integers. 我想创建一个算法,找到所有可以使用4个基本操作创建的值+ - * /来自数字n的列表,其中2 <= len(l) <= 6n >= 1所有数字必须是整数。 I have seen a lot of similar topics but I don't want to use the itertool method, I want to understand why my recursive program doesn't work 我看过很多类似的主题,但我不想使用itertool方法,我想了解为什么我的递归程序不起作用

I tried to make a costly recursive program that makes an exhaustive search of all the possible combinations, like a tree with n=len(l) start and each tree depth is n . 我试图制作一个代价高昂的递归程序,对所有可能的组合进行详尽的搜索,比如n=len(l) start的树,每个树的深度为n

  • L list of the starting number L列表的起始编号
  • C the current value C当前值
  • M the list of all possible values M所有可能值的列表

My code: 我的代码:

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

For small lists without duplicate numbers, my algorithm seems to work but with lists like [1,1,2,2,4,5] it misses some values. 对于没有重复数字的小列表,我的算法似乎有效,但是像[1,1,2,2,4,5]这样的列表却错过了一些值。

It returns: 它返回:

[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]

but it misses 93,108,114,117,123,126,132,135,150,180 . 但它错过了93,108,114,117,123,126,132,135,150,180

Let's take an even simpler example: [1, 1, 2, 2] . 让我们举一个更简单的例子: [1, 1, 2, 2] 1,1,2,2 [1, 1, 2, 2]

One of the numbers your algorithm can't find is 9 = (1 + 2) * (1 + 2) . 您的算法找不到的数字之一是9 = (1 + 2) * (1 + 2)

Your algorithm simply cannot come up with this computation because it always deals with a "current" value C . 您的算法根本无法提出此计算,因为它始终处理“当前”值C You can start with C = 1 + 2 , but you cannot find the next 1 + 2 because it has to be constructed separately. 您可以从C = 1 + 2 ,但是您无法找到下一个1 + 2因为它必须单独构建。

So your recursion will have to do at least some kind of partitioning into two groups, finding all the answers for those and then doing combining them. 因此,您的递归必须至少进行某种分区,分成两组,找到所有答案,然后将它们组合起来。

Something like this could work: 像这样的东西可以工作:

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

Not too efficient though. 虽然效率不高。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM