2011-12-28 18 views
3

产量子组合,我与Python 3.我正在使用该功能的工作如下:与限制

def sub_combinations(segment): 
    if len(segment) == 1: 
    yield (segment,) 
    else: 
    for j in sub_combinations(segment[1:]): 
     yield ((segment[0],),)+j 
     for k in range(len(j)): 
     yield (((segment[0],)+j[k]),) + (j[:k]) +(j[k+1:]) 

了一个版本的功能:

Yielding sub combinations

(1,2,3,4,5)的输出如下:

((1,), (2,), (3,), (4,), (5,)) 
((1, 2), (3,), (4,), (5,)) 
((1, 3), (2,), (4,), (5,)) 
((1, 4), (2,), (3,), (5,)) * 
((1, 5), (2,), (3,), (4,)) * 
((1,), (2, 3), (4,), (5,)) 
((1, 2, 3), (4,), (5,)) 
((1, 4), (2, 3), (5,)) * 
((1, 5), (2, 3), (4,)) * 
((1,), (2, 4), (3,), (5,)) 
((1, 2, 4), (3,), (5,)) 
((1, 3), (2, 4), (5,)) 
((1, 5), (2, 4), (3,)) * 
((1,), (2, 5), (3,), (4,)) * 
((1, 2, 5), (3,), (4,)) * 
((1, 3), (2, 5), (4,)) * 
((1, 4), (2, 5), (3,)) * 
((1,), (2,), (3, 4), (5,)) 
((1, 2), (3, 4), (5,)) 
((1, 3, 4), (2,), (5,)) 
((1, 5), (2,), (3, 4)) * 
((1,), (2, 3, 4), (5,)) 
((1, 2, 3, 4), (5,)) 
((1, 5), (2, 3, 4)) * 
((1,), (2, 5), (3, 4)) * 
((1, 2, 5), (3, 4)) * 
((1, 3, 4), (2, 5)) * 
((1,), (2,), (3, 5), (4,)) 
((1, 2), (3, 5), (4,)) 
((1, 3, 5), (2,), (4,)) 
((1, 4), (2,), (3, 5)) * 
((1,), (2, 3, 5), (4,)) 
((1, 2, 3, 5), (4,)) 
((1, 4), (2, 3, 5)) * 
((1,), (2, 4), (3, 5)) 
((1, 2, 4), (3, 5)) 
((1, 3, 5), (2, 4)) 
((1,), (2,), (3,), (4, 5)) 
((1, 2), (3,), (4, 5)) 
((1, 3), (2,), (4, 5)) 
((1, 4, 5), (2,), (3,)) * 
((1,), (2, 3), (4, 5)) 
((1, 2, 3), (4, 5)) 
((1, 4, 5), (2, 3)) * 
((1,), (2, 4, 5), (3,)) 
((1, 2, 4, 5), (3,)) 
((1, 3), (2, 4, 5)) 
((1,), (2,), (3, 4, 5)) 
((1, 2), (3, 4, 5)) 
((1, 3, 4, 5), (2,)) 
((1,), (2, 3, 4, 5)) 
((1, 2, 3, 4, 5),) 

问题是,如果我工作机智h较大的元组时,函数sub_combinations会返回大量数据,并且计算时间过长。为了解决这个问题,我想通过添加一个额外的参数来限制返回的数据量。例如,sub_combinations((1,2,3,4,5),2)应该返回上面的数据,但没有标有星号的元组。因为元组中的连续值之间的偏移量大于2,所以这些被删除。例如,包含(1,4),(1,5)或(2,5)等的行(1,2,5)被丢弃。要调整

线

for k in range(len(j)) 

需要删除这些行,但我还没有想出如何。有什么建议么?

巴里

回答

1

我想在下面的输出变化的结果,你正在寻找:

def sub_combinations(segment, max_offset=None): 
    data = tuple([e] for e in segment) 
    def _sub_combinations(segment): 
     if len(segment) == 1: 
     yield (segment,) 
     else: 
     for j in _sub_combinations(segment[1:]): 
      yield ((segment[0],),)+j 
      for k in range(len(j)): 
       if max_offset and data.index(j[k][0]) - data.index(segment[0]) > max_offset: 
        break 
       yield (((segment[0],)+j[k]),) + (j[:k]) +(j[k+1:]) 
    for combination in _sub_combinations(data): 
     yield tuple(tuple(e[0] for e in t) for t in combination) 

这里的想法是,你跳出k循环,而不是产生一个元组将有大于max_offset的偏移量。

+0

(1,2,3,4,5)只是一个例子。 (“H”,“E”,“L”,“P”)也是这个函数的有效参数,它不会与你的代码一起工作。 – Baz 2011-12-29 09:54:47

+0

只要将每个字母视为其ASCII码的十进制形式(将所有字母标准化为大写或小写之后),并且该代码仍然可以工作。 – 2011-12-29 18:08:14

+0

@Baz - 它现在应该可以处理任意输入,但它也有点复杂。 – 2011-12-29 18:08:47