【问题标题】:Generating subsets recursively solution in a specific order以特定顺序递归生成子集解决方案
【发布时间】:2021-10-24 02:52:58
【问题描述】:

我遇到了以下问题,我不确定如何解决:

按照数字在给定输入集中出现的顺序打印除空集以外的所有子集。

Sample input:
5 3 8

Sample output:
5
3
8
53
58
38
538

我的问题是,我该怎么做?我知道要生成所有子集,我可以使用以下代码(在 python 中):

numbers = [5, 3, 8]

n = len(numbers)

ans = [0] * n

def subset(pos):
    if pos == n:
        print(ans)
        return

    ans[pos] = 0
    subset(pos + 1)
    ans[pos] = 1
    subset(pos + 1)

subset(0)

【问题讨论】:

  • 既然喜欢python,有没有试过itertoolspowerset配方?见stackoverflow.com/a/68032938/3080723
  • 我可以使用 BFS 在 C++ 中发布答案。我不知道它是否对你有帮助,但你会明白它背后的基本思想。
  • 谢谢@Stef 我想纯粹递归地解决这个问题,因为我希望建立我的理解。即我想自己实现逻辑。 risingStark,如果可以的话,那确实会有所帮助。我熟悉 BFS,只是不熟悉如何递归地解决这个问题。

标签: python algorithm recursion subset


【解决方案1】:

另一种递归方法:

要得到'abc'的幂集,取'bc'的幂集,然后在每个元素前面加上'a',或者不加。

def powerset(seq):
  if len(seq) == 0:
    return [[]]
  else:
    p = powerset(seq[1:])
    return [[seq[0]]+c for c in p] + p

print(powerset('abc'))
# [['a', 'b', 'c'], ['a', 'b'], ['a', 'c'], ['a'], ['b', 'c'], ['b'], ['c'], []]
# |_____________________________________________|  |___________________________|
#        powerset of 'bc' with 'a' in front               powerset of 'bc'

【讨论】:

  • 感谢@Stef,这非常优雅。我想我需要更多的练习才能爬上这堵递归墙。
  • @finite_diffidence 人们常说函数式编程和递归实际上比命令式编程和迭代更容易、更自然。提出递归函数的一个技巧是想象你的一个朋友已经解决了这个问题,但他的解决方案有一个限制,只能处理大小为n-1 的项目。所以你所要做的就是编写一个函数,接收大小为n 的项目,将它们分解为最多n-1 大小的项目,然后调用你朋友的函数,并使用该调用的结果来计算结果适合您的情况。
  • 这里我用powerset(seq[1:])的结果来计算powerset(seq)的结果
【解决方案2】:

您可以使用以下算法:

  • 让大小从 1 增加到输入的大小。
  • 对于每个大小,使用递归从列表中选择那么多元素。

我猜你正在寻找算法,所以虽然我会在这里使用 Python,但我不会使用 itertools 之类的库。

def subsets(values):
    result = []

    def recur(start, size, selection):
        if not size:
            result.append(selection)
        else:
            for i in range(start, len(values) - size + 1):
                recur(i + 1, size - 1, selection + [values[i]])
    
    for size in range(1, len(values)+1):
        recur(0, size, [])

    return result

# Example run:
result = subsets([3, 8, 5])
print(res)

【讨论】:

  • 谢谢@trincot,这很清楚。看来我需要花更多时间来掌握递归。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 2015-10-25
相关资源
最近更新 更多