使用减少和征服从较大的集合中查找大小为k的子集

时间:2014-10-07 19:59:58

标签: python algorithm divide-and-conquer

披露:这是作业。我试图提供满足SO规则所需的所有信息;如果我错过了什么,我道歉。

我正在使用Python,我需要从n个整数列表(非重复排列)生成长度为k的所有子集。该计划需要是一个减少和征服计划。我想我已经使用下面提供的代码走上了正确的轨道,但我无法在它与最终解决方案之间建立联系。 我不是要求解决方案,只是为了帮助我指明正确的方向。

我很确定我可以轻松地迭代地执行此操作(这是错误的,如评论中所示)

  • 使用i = 0j = k-1初始化两个循环
    • 打印从A[i]A[i+k-1]
    • 的三个元素
    • 打印A[j]
    • 递增j,直至到达列表末尾
  • 增加i,重复直到i == n - k - 1

然而,我并不确定如何将其转化为减少和征服的功能。我知道我需要使用某种递归,当然,但我不知道如何使用递归来实现这个功能。我知道这是完全错误的,但这是我到目前为止编写的代码。

def permutations(A, k):
    if len(A) < k:
        print "Step:"
        print A
        return A
    else:
        new = []
        new = permutations(A[:-2], k)       
        new.append(A[-1])
        return new

if __name__ == '__main__':
    useList = [10, 20, 30, 40, 50, 60, 70, 80]
    useK = 3
    final = permutations(useList, useK)
    print "Final list:"
    print final

此代码生成以下输出(“Step”用于调试):

Step:
[10, 20]
Final list:
[10, 20, 40, 60, 80]

忽略调试的“Step”,输出应该与此类似(尽管显示最终结果的确切方法/顺序无关紧要):

[10, 20, 30]
[10, 20, 40]
[10, 20, 50]
...

...每个3个整数子集有一个条目。一旦达到[10,20,80],我们将继续[20,30,40]等。

1 个答案:

答案 0 :(得分:0)

我最后要求我的教授寻求进一步的帮助。使用的方法涉及生成二进制字符串列表,其中1是&#34;激活&#34; index和0是&#34; inactivated&#34;指数。一旦生成了二进制字符串,使用它们生成子集列表就很简单了。

最终(评论)代码如下。我将输出留出以节省空间;该程序可以很容易地运行。

#create list of binary strings representing indices of all subsets of k elements from a
#list n elements long
def permutations(n, k):
    #base case 1: handles the recursion where n-1 and k are being passed to the function
    #return n 1's in a string: '1...1'
    if n == k:
        s = str()        #initialize s as an empty list
        m = 0
        while m < n:     #loop from 0 (empty list) to n elements in the list
            s += '1'     #append the number 1 as an element to the list
            m += 1
        return [s]       #return the list back from the recursion

    #base case 2: handles the recursion where n-1 and k-1 are being passed to the function
    #return n 0's in a string: '0...0'; empty string if n == 0
    elif k == 0:
        s = str()        #initialize s as an empty list
        m = 0
        while m < n:     #loop from 0 (empty list) to n elements in the list
            s += '0'     #append the number 0 as an element to the list
            m += 1
        return [s]       #return the list back from the recursion
    else:
        listN_1 = permutations(n - 1, k)
        listK_1 = permutations(n - 1, k - 1)

        listN = []
        for item in listN_1:
            listN.append(str(item) + '0')
        for item in listK_1:
            listN.append(str(item) + '1')
        return listN

#return subsets from a given list using a list of binary strings
def convertPerms(bStrings, useList):
    final = []              #initialize empty list to be returned by function
    for item in bStrings:   #loop through each list element (each binary string)
        l = []              #initialize list for THIS binary string iteration
        item = list(item)
        for (i, s) in enumerate(item):   #iterate through binary string, including keys
            if int(s) == 1:                   #if value == 1...
                l.append(useList[i])     #...append useList item at this index to THIS string's list

        final.append(l)   #append THIS string's list to final list
    return final   #return final list

if __name__ == '__main__':
    useList = [10, 20, 30, 40, 50, 60, 70, 80]
    useK = 3
    perms = permutations(len(useList), useK)
    final = convertPerms(perms, useList)
    print "Final list:"
    for item in final:
        print item