我需要递归地进行以下计算。
对于1到30之间的任何n,我需要考虑从1到n的所有可能的加法或减法组合。所以,例如,如果n = 5:
1 ± 2 ± 3 ± 4 ± 5 ± 6 = ?;
我需要找到与数字本身相等的可能表达式的数量。因此,对于n = 5,只有以下两个表达式等于5:
5 = 1 + 2 + 3 + 4 − 5
5 = 1 − 2 − 3 + 4 + 5
我的方法
我想出了如何创建递归树,其中每个递归级别将添加或减去“深度”。因此,在最后的深度,节点已经有了计算的总和 - 我所要做的就是检查它们是否等于初始数。
这样可以正常工作,但是在数字大于n> 26时,我会遭受巨大的内存消耗,并且程序耗时太长。一点点数学就清楚了解原因。 那么我该如何优化呢?我一直试图把它变成尾递归,但它对我不起作用......当我有两个递归调用时,我根本不理解如何实现它。
这是我的代码:
树结构和创建功能
typedef struct nodes {
unsigned int value;
struct node* pos;
struct node* neg;
} node;
node* addNode(int data){
node* newNode = (node*)malloc(sizeof(node));
newNode->value = data;
newNode->pos = NULL;
newNode->neg = NULL;
return newNode;
}
构建我的树的功能
node* buildTree(int depth, int data){
node* nNode = addNode(1);
if(depth==n+1){
if(data == n) {
result++;
}
return nNode;
}
else{
nNode->pos = buildTree(depth+1,data+depth);
nNode->neg = buildTree(depth+1,data-depth);
return nNode;
}
}
全球范围变量&主
int result = 0;
int n;
int main(int argc, char **argv)
{
scanf("%i",&n);
buildTree(2,1); //build tree starting with recursion depth = 2, first node value = 1.
printf("%i\n",result);
return 0;
}
请帮忙 - 我已经坚持了很长时间。
答案 0 :(得分:1)
我认为你不需要树。
一些简单的递归应该这样做:
#include <stdio.h>
void f(int current_sum, int current_depth, int target_depth)
{
if (current_depth > target_depth)
{
// Here you have the final result for this path
printf("%d\n", current_sum);
return;
}
f(current_sum+current_depth, current_depth+1, target_depth);
f(current_sum-current_depth, current_depth+1, target_depth);
}
int main(void) {
f(0, 1, 3); // I use n=3
return 0;
}
输出:
6
0
2
-4
4
-2
0
-6
提示:通过注意后半部分数字是上半部分的负数,您可以大大提高运行时性能。使用类似的东西:
f(current_sum+current_depth, current_depth+1, target_depth);
if (current_depth != 1)
{
f(current_sum-current_depth, current_depth+1, target_depth);
}
实现这一点。