如何在" x"之前计算所有元素的总和?元素递归?

时间:2018-04-27 12:45:30

标签: c

我正在编写一个程序,在递归x元素之前计算所有元素的摘要。它总是返回0.请帮助我 - 你能解释一下当我在main中调用SumBeforeX函数时它是如何有效地工作的吗? 这是我的代码和

#include <stdio.h>
int SumBeforeX(int a[], int n, int x)
{
    int i = 0;
    static int s = 0;
    if (n == 0)
        return 0;
    if (a[i] == x)
        s+=SumBeforeX(a, i -1, x) +a[i-1];
    return s;

}
void main()
{
    int a[] = {2,6,13,17,47,8};
    printf("%d",SumBeforeX(a,6,13));
    _getch();
}

3 个答案:

答案 0 :(得分:2)

user3629249 给出的答案已经解释了为什么SumBeforeX()总是返回0 Felix Palmen 回答谈到了递归和非递归方式解决问题。这个答案只是为了让您了解使用尾递归计算"x"元素之前的总和:

int SumBeforeX(const int *a, int n, int x, int sum)
{
    if (n == 0) return 0;
    if (x == *a) return sum;

    return SumBeforeX(a + 1, n - 1, x, sum + *a);
}

在这里,您可以看到我已向函数sum添加了一个参数SumBeforeX,并将元素总和累积到其中。你可以这样称呼它:

printf("%d\n", SumBeforeX(a, 6, 13, 0));

似乎你正在学习递归,它也很适合熟悉尾递归。

如果函数返回后除了返回其值之外没有任何操作,则称函数调用是尾递归的。尾递归函数可以很容易地转换为迭代函数,因此编译器也可以通过消除递归来优化这些函数的代码,也就是说,尾递归调用在常量堆栈空间中运行,即它们不需要创建新的堆栈当他们递归地调用自己时的帧。检查以下内容以获得更好的想法:
1)Tail Recursion
2)How exactly does tail recursion work?

答案 1 :(得分:0)

我想预期的解决方案看起来有点像这样:

int sumBeforeX(const int *a, int x)
{
    if (x == *a) return 0;           // termination condition
    return *a + sumBeforeX(a+1, x);  // recursive step
}

要理解这一点,请注意,数组不能在C中传递,因此它们在函数参数中的类型会调整为相应的指针类型,而是传递指向第一个元素的指针。我在上面的代码片段中明确说明了这一点,直接写了指针类型。

const只是一点改进:函数永远不会通过这个指针修改你的数组,所以也要明确这个。

另请注意此实施从不指定的任何内容。这是函数式编程的典型属性,递归特别适用于函数式编程。函数调用没有副作用

旁注:不要在现实世界的C代码中递归写入,如果幸运的话,编译器会优化递归(在这个简单的情况下,一个好的编译器应该这样做),但是不应该这样做如果递归保持不变,性能通常会受到影响,如果递归真的很深,你可能会遇到堆栈溢出的风险。因此,为了完整性,现实世界的代码看起来应该更像:

int sumBeforeX(const int *a, int x)
{
    int sum = 0;                  // accumulator to replace recursion
    while (*a != x) sum += *a++;
    return sum;
}

答案 2 :(得分:0)

关于:当我在main中调用SumBeforeX函数时,你能解释它是如何有效运作的吗?

#include <stdio.h>
int SumBeforeX(int a[], int n, int x)
{
    int i = 0;
    static int s = 0;
    if (n == 0)
        return 0;
    if (a[i] == x)
        s+=SumBeforeX(a, i -1, x) +a[i-1];
    return s;

}
void main()
{
    int a[] = {2,6,13,17,47,8};
    printf("%d",SumBeforeX(a,6,13));
    _getch();
}

首次执行SumBeforex()

  1. n的值为6,因此没有提前退出
  2. s的值为0
  3. i的值为0,因此a[i]的值为2
  4. x的值为13
  5. 所以`if(a [i] == x)是假的
  6. 因此,不会发生任何递归
  7. 所以0返回'main()`
  8. 所以打印值为0