在Java中将迭代函数转换为递归

时间:2019-07-07 21:19:40

标签: java

我想将此函数转换为递归形式,有人可以帮我吗 该功能就是解决这些问题

X=1+(1+2)*2+(1+2+3)*2^2+(1+2+3+4)*2^3+ . . . +(1+2+3+4+. . . +n)*2^(n-1) 
public static int calcX(int n) {
        int x=1;
        int tmp;
        for(int i = 1 ; i <= n-1;i++) {
            tmp=0;
            for(int j = 1 ; j <= i + 1;j++) {
                tmp+=j;
            }
            x+=tmp*Math.pow(2, i);
        }
        return x;
    }

我对递归方法的新尝试

public static int calcXrecu(int n,int tmp,int i,int j) {
        int x=1;
        if(i <= n-1) {
            if(j <= i) {
                calcXrecu(n,tmp+j,i,j+1);
            }
            else {
                x = (int) (tmp*Math.pow(2, i));
            }
        }
        else {
            x=1;
        }
            return x;
    }

2 个答案:

答案 0 :(得分:3)

您有一系列的和,它们本身就是和。
n项可以像这样从第(n-1)项导出:

a(n) = a(n-1) + (1+2+3+....+n) * 2^(n-1)  [1]

这是递归公式,因为它通过前一项生成每个项。
现在您需要另一个1+2+3+....+n的公式(高中数学):

1+2+3+....+n = n * (n + 1) / 2  [2]

现在在[2]中使用[1]

a(n) = a(n-1) + n * (n + 1) * 2^(n-2)  [3] 

因此,您有一个公式,可以根据该公式从上一个术语导出每个术语,这就是递归方法所需要的:

public static int calcXrecu(int n) {
    if (n == 1) return 1;
    return calcXrecu(n - 1) + n * (n + 1) * (int) Math.pow(2, n - 2);
}

此行:

if (n == 1) return 1;

是递归的退出点。
请注意,Math.pow(2, n - 2)需要转换为int,因为它返回Double

答案 1 :(得分:0)

除了@forpas答案,我还想通过利用Stream.iterate提供使用corecursion的解决方案。这显然不是递归解决方案,但我认为也知道替代方法也是一件好事。请注意,我使用对来表示(索引,值)的元组。

public static int calcXcorecu(final int n) {
    return Stream.iterate(
            Pair.of(1, 1), p -> {
                final int index = p.getLeft();
                final int prev = p.getRight();
                final int next = prev + index * (index + 1) * (int) Math.pow(2, index - 2);
                return Pair.of(index + 1, next);
            })
            // only need the n-th element
            .skip(n)
            .limit(1)
            .map(Pair::getRight)
            .findFirst()
            .get();
}