Recursion 使用递归的数列

Recursion 使用递归的数列,recursion,sequence,Recursion,Sequence,我想计算这样的数字序列: n*(n-1)+n*(n-1)*(n-2)+n*(n-1)*(n-2)*(n-3)+n*(n-1)*(n-2)*(n-3)*(n-4)+...+n(n-1)...(n-n) 例如n=5和sum=320 我有一个函数,它计算一个元素: int fac(int n, int s) { if (n > s) return n*fac(n - 1, s); return 1; } 好的,没有什么好写的。如果你想解决这个问题,我建议两种方

我想计算这样的数字序列:

n*(n-1)+n*(n-1)*(n-2)+n*(n-1)*(n-2)*(n-3)+n*(n-1)*(n-2)*(n-3)*(n-4)+...+n(n-1)...(n-n)
例如
n=5
和sum=320

我有一个函数,它计算一个元素:

int fac(int n, int s)
{
    if (n > s)
        return n*fac(n - 1, s);
    return 1;
}

好的,没有什么好写的。如果你想解决这个问题,我建议两种方法。(由于重现的能力,复杂性是一团混乱,运行时间将随着大量数据的增加而急剧增加!)

int func(int n){
返回函数(n,2);
}
int func(int n,int i){
if(ia){
返回i*fac(i-1,a);
}否则返回1;
}
像这样的东西

function fac(int n, int s)
{
    if (n >= s)
        return n * fac(n - 1, s);
    return 1;
}

int sum = 0;
int s = 4;
n = 5;
while(s > 0)
{
    sum += fac(n, s);
    s--;
}
print sum; //320
无循环版本:

int fac(int n, int s)
{
    if (n >= s)
        return n * fac(n - 1, s);
    return 1;
}

int compute(int n, int s, int sum = 0)
{
    if(s > 0)
        return compute(n, s - 1, sum + fac(n, s));
    return sum;
}

print compute(5, 4); //320

重新计算每个求和的阶乘是相当浪费的。相反,我建议使用备忘录。如果你重新订购

n*(n-1) + n*(n-1)*(n-2) + n*(n-1)*(n-2)*(n-3) + n*(n-1)*(n-2)*(n-3)*...*1
你得到

n*(n-1)*(n-2)*(n-3)*...*1 + n*(n-1)*(n-2)*(n-3) + n*(n-1)*(n-2) + n*(n-1)
注意你是如何从1..n的乘积开始的,然后你加上1..n除以1的乘积,然后你加上除以1*2的乘积,以此类推

我认为函数更有效的定义是(在Python中):

此定义的递归版本为:

def f(n):
    def go(sum_, i):
        if i >= n-1:
            return sum_
        return sum_ + go(sum_ / i, i+1)
    return go(product(range(1, n+1)), 1)
最后但并非最不重要的一点是,您还可以通过使用
reduce
生成求和列表来定义函数,而无需任何显式递归(这是一种更“功能性”的方式,就像在函数式编程风格中一样):

这种风格在Haskell等函数式编程语言中非常简洁;Haskell有一个函数调用
scanl
,它简化了求和的生成,因此定义如下:

f n = sum $ scanl (/) (product [1..n]) [1..(n-2)]

这是一个很好的解决方案,但我想知道是否可以在一个递归中计算和?您可以使用额外的while循环来计算sum。我正在寻找无循环的Version:)@ElConrado我编辑了答案,虽然Rection比循环解决方案使用了大量的资源,谢谢,我认为这是一个不错的答案,但是它使用了两个函数,但是如果有连接,它将是两个调用。最后的和总是为零(因为你要乘以
n-n
).是的,最好像你在下面的回答中那样写这个序列。是的,谢谢。这是个好办法。但这不是递归解决方案。@ElConrado:我现在添加了一个递归版本。
def f(n):
    def go(sum_, i):
        if i >= n-1:
            return sum_
        return sum_ + go(sum_ / i, i+1)
    return go(product(range(1, n+1)), 1)
def f(n):
    summands, _ = reduce(lambda (lst, p), i: (lst + [p], p / i),
                         range(1, n),
                         ([], product(range(1, n+1))))
    return sum(summands)
f n = sum $ scanl (/) (product [1..n]) [1..(n-2)]