使用递归的数字序列

时间:2015-03-06 12:51:55

标签: 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;
}

3 个答案:

答案 0 :(得分:2)

重新计算每个summand的阶乘是非常浪费的。相反,我建议使用memoization。如果你重新订购

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):
    p = product(range(1, n+1))
    sum_ = p
    for i in range(1, n-1):
        p /= i
        sum_ += p
    return sum_

此定义的递归版本为:

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生成加数列表来定义函数而不进行任何显式递归(这是一个更“实用”的函数 - 如函数式编程一样):

def f(n):
    summands, _ = reduce(lambda (lst, p), i: (lst + [p], p / i),
                         range(1, n),
                         ([], product(range(1, n+1))))
    return sum(summands)

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

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

答案 1 :(得分: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

答案 2 :(得分:0)

好的不是写的。如果你想解决这个rec​​ursiv,我会建议2个方法。 (recrusiv教员的Becaus复杂性是一团糟,运行时间会大幅增加!)

  int func(int n){
     return func(n, 2);
   }

   int func(int n, int i){
        if (i < n){
           return n*(fac(n-1,n-i)+func(n, i + 1));      
        }else return 0;
    }


     int fac(int i,int a){
         if(i>a){
           return i*fac(i-1, a);
         }else return 1;
      }