从集合索引构建单个集合元素

时间:2018-03-13 10:30:55

标签: python

假设数组lst的索引是一个集合。在下面的程序中,我打印了阵列lst的k = 1,2,3的所有可能的唯一子集。如您所见,每个子集元素都有一个计数器。例如,元素23具有子集元素(3,5)。我想要做的是,只有访问计数器,我希望能够构建元素,例如,如果我的计数器值为23,我应该能够创建(3,5)。显然,我想这样做而不将所有这些可能的组合存储在内存中。任何人都可以帮助我吗?

lst = [0,1,2,3,4,5,6]

counter=0
for i in range(len(lst)):
    print("counter:",counter,"(",i,")", end="\t")
    counter+=1
print()

for i in range(len(lst)):
    for j in range(i+1,len(lst),1):
        print("counter:",counter,"(",i,",",j,")", end="\t")
        counter+=1
    print()


for i in range(len(lst)):
    for j in range(i+1,len(lst),1):
        for k in range(j+1,len(lst),1):
            print("counter:",counter,"(",i,",",j,",",k,")", end="\t")
            counter+=1
    print()

结果:

counter: 0 ( 0 )    counter: 1 ( 1 )    counter: 2 ( 2 )    counter: 3 ( 3 )    counter: 4 ( 4 )    counter: 5 ( 5 )    counter: 6 ( 6 )    
counter: 7 ( 0 , 1 )    counter: 8 ( 0 , 2 )    counter: 9 ( 0 , 3 )    counter: 10 ( 0 , 4 )   counter: 11 ( 0 , 5 )   counter: 12 ( 0 , 6 )   
counter: 13 ( 1 , 2 )   counter: 14 ( 1 , 3 )   counter: 15 ( 1 , 4 )   counter: 16 ( 1 , 5 )   counter: 17 ( 1 , 6 )   
counter: 18 ( 2 , 3 )   counter: 19 ( 2 , 4 )   counter: 20 ( 2 , 5 )   counter: 21 ( 2 , 6 )   
counter: 22 ( 3 , 4 )   counter: 23 ( 3 , 5 )   counter: 24 ( 3 , 6 )   
counter: 25 ( 4 , 5 )   counter: 26 ( 4 , 6 )   
counter: 27 ( 5 , 6 )   

counter: 28 ( 0 , 1 , 2 )   counter: 29 ( 0 , 1 , 3 )   counter: 30 ( 0 , 1 , 4 )   counter: 31 ( 0 , 1 , 5 )   counter: 32 ( 0 , 1 , 6 )   counter: 33 ( 0 , 2 , 3 )   counter: 34 ( 0 , 2 , 4 )   counter: 35 ( 0 , 2 , 5 )   counter: 36 ( 0 , 2 , 6 )   counter: 37 ( 0 , 3 , 4 )   counter: 38 ( 0 , 3 , 5 )   counter: 39 ( 0 , 3 , 6 )   counter: 40 ( 0 , 4 , 5 )   counter: 41 ( 0 , 4 , 6 )   counter: 42 ( 0 , 5 , 6 )   
counter: 43 ( 1 , 2 , 3 )   counter: 44 ( 1 , 2 , 4 )   counter: 45 ( 1 , 2 , 5 )   counter: 46 ( 1 , 2 , 6 )   counter: 47 ( 1 , 3 , 4 )   counter: 48 ( 1 , 3 , 5 )   counter: 49 ( 1 , 3 , 6 )   counter: 50 ( 1 , 4 , 5 )   counter: 51 ( 1 , 4 , 6 )   counter: 52 ( 1 , 5 , 6 )   
counter: 53 ( 2 , 3 , 4 )   counter: 54 ( 2 , 3 , 5 )   counter: 55 ( 2 , 3 , 6 )   counter: 56 ( 2 , 4 , 5 )   counter: 57 ( 2 , 4 , 6 )   counter: 58 ( 2 , 5 , 6 )   
counter: 59 ( 3 , 4 , 5 )   counter: 60 ( 3 , 4 , 6 )   counter: 61 ( 3 , 5 , 6 )   
counter: 62 ( 4 , 5 , 6 )   

2 个答案:

答案 0 :(得分:0)

考虑powerset函数的这个定义:

def compress(it, n):
    for v in it:
        if n & 1:
            yield v
        n >>= 1

def powerset(s):
    return [compress(s, i) for i in range(1 << len(s))]

以二进制顺序枚举子集。

答案 1 :(得分:0)

我没有完整的答案,只有一些提示可以指导你的推理。您可以将您的指数视为扭曲的数字系统,其中您没有每个计算位置的所有数字。

n = len(lst)则1索引子集的数量为n1 = n,2索引子集的数量为n2 = n*(n+1)//2 - n1,3索引子集的数量为n3 = n*(n+1)*(n+2)//8 - n2 - n1在你的例子中,n1 = 7,n2 = 21,n3 = 35,当然n1 + n2 + n3 = 63

所以我猜测执行欧几里得分解的一些变体,在n1n2n3上使用组合的//和%运算符应该提供正确的子集。但这并非完全无足轻重......