【问题标题】:Finding subsets of size k from a larger set using decrease-and-conquer使用减少和征服从更大的集合中找到大小为 k 的子集
【发布时间】:2014-12-02 08:46:36
【问题描述】:

披露:这是作业。我正在尝试提供满足 SO 规则所需的所有信息;如果我遗漏了什么,我深表歉意。

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

我很确定我可以轻松地迭代地做到这一点(这是不正确的,如 cmets 所示)

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

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

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

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

【问题讨论】:

  • 排列有两种类型,重复和不重复。你想实现哪一个?
  • 啊,好点子,谢谢。不重复。我已经相应地编辑了帖子。
  • 那段代码做了什么?你得到什么输出,你期望什么?
  • 你能举个例子吗?使用集合 {10, 20, 30, 40} 和 k=2,函数应该输出什么?
  • @jonrsharpe:我现在已经用该信息更新了原始帖子。

标签: python algorithm divide-and-conquer


【解决方案1】:

我最终向我的教授寻求进一步的帮助。使用的方法涉及生成二进制字符串列表,其中 1 是“激活”索引,0 是“未激活”索引。生成二进制字符串后,使用它们生成子集列表就很简单了。

最终(注释)代码如下。我将把输出留在外面以节省空间;该程序可以很容易地运行。

#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

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2018-09-06
    • 2017-09-09
    • 2018-08-04
    • 1970-01-01
    • 2014-07-25
    • 2017-11-08
    • 1970-01-01
    相关资源
    最近更新 更多