我需要计算一个非常奇怪的函数,我在java中有一个复杂的递归。在递归的某个时刻,我需要使用n的每个成分进行一些计算,使用k或更少的部分。
换句话说,我需要能够准确地获取每个合成一次并存储它,以便我可以对它进行一些操作,从中获取一个数字,将其添加到计数器然后继续下一个作文。我正在使用java,你知道我该怎么做吗?
作为一个例子,考虑一种算法,该算法在查看大小为k的所有n个组合时计算大小为5的部分的次数。
答案 0 :(得分:1)
这是在python中,我相信你可以很容易地在Java中使用它。
由于您需要唯一的分区 - 也就是说,您认为(1, 4)
和(4. 1)
是同一个分区 - 因此按顺序生成组件很方便。按顺序生成它们会稍微简单一些。
这意味着如果我们生成了第一个j
组件(j < k
),则生成的最后一个组件为p
,到目前为止生成的组件总和为{{1 (s
),然后我们可以使用s < n
的任何分区结束,其中最小大小为n - s
的{{1}}组件不会超过k - j
。
换句话说,我们想要一个三参数递归函数。但是当我们找到分区时,我们还需要考虑在递归底部我们做了什么。在python中,我们只能s
,但在其他语言中,我们可以通过递归传递函数,并在分区上调用函数。这可能是Java或C ++中最简单的解决方案,所以我将以这种方式对python解决方案进行建模。它还使用了一个固定长度的数组,它有点unpythonic但在Java中可能会更好。
仔细分析递归将显示如何从一个向量迭代到下一个向量。但那是值得怀疑的,恕我直言。
yield
分区计数增长很快。有(如果上面没有错误)596,763个分区,k = 7,n = 100;其中150,224包括至少一个5号组件。
供参考,原始python(3.3+),使用# v: vector of size k
# k: max parts
# (redundant: it's len(v))
# i: number of parts already in the vector
# n: elements left to partition
# s: minimum size of next part
# (redundant: it's v[i - 1] unless i = 0, in which case it's 1)
# act(v, i): action to call with vector and number of parts
# Invariants: s <= n; i < k
def genpart_helper(v, k, i, n, s, act):
# We can always use everything which is left
v[i] = n;
act(v, i + 1)
# If there is more than one part left, and we have
# at least the twice the minimum number of elements left,
# we can recurse
if i + 1 < k:
# This is python for: "for (int j = n/2; j >= s; --j)"
for j in range(n // 2, s - 1, -1):
v[i] = j
genpart_helper(v, k, i + 1, n - j, j, act)
# The top-level call. Checks the invariant, creates the vector,
# and calls the recursive function
def genparts(n, k, act):
if k <= n and k >= 1:
genpart_helper([0]*k, k, 0, n, 1, act)
:
yield
答案 1 :(得分:0)
如果它是一个递归功能,你需要......我有一个想法,但你必须先尝试编码。在这里,我们希望您先尝试,当您有疑虑时,请发布问题。然而...
我认为这个问题的关键是找到一个基本情况,就像“给定一个k
长度的数组填充1
s,add 1
到每个位置,直到当你n
的职位时,你得到sum up all
。例如:
找到n = 5的长度k = 3的成分。