【问题标题】:Incorrect output from recursive function to compute sum of digits of a number递归函数的输出不正确以计算数字的数字总和
【发布时间】:2011-08-12 19:13:02
【问题描述】:

我试图编写一个函数,该函数将使用递归计算数字的数字之和,但输出不正确。代码如下:

/*Write a function to calculate sum of digits of a  number using recursion*/
/*Author:Udit Gupta     Date:10/08/2011*/

#include<stdio.h>

int sum (int);

int main () {
    int n,s;

    printf ("Enter the number:");
    scanf ("%d",&n);

    s = sum (n);
    printf ("The sum of the digits of the number is %d",s);
}


int sum (int a) {
    int f;

    if (a == 0) {
         return f;
    }
    f = (a% 10) + sum (a/10);
}

以下是一些输出值:

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:123
 The sum of the digits of the number is 7

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:1234
 The sum of the digits of the number is 2919930

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:123456
 The sum of the digits of the number is 4620297

 udit@udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
 Enter the number:12345
 The sum of the digits of the number is 15  /*Only this one seems correct*/

谁能帮我弄清楚为什么这不能正常工作?

【问题讨论】:

  • 输出对于 5 位数字很好,但高于和低于 5 位数字会给出错误的结果。
  • 输出是什么?请编辑您的问题以包括示例输入、预期输出和实际输出。
  • 这不是论坛。问题就像 wiki 一样工作。 请将输出放入您的问题中。
  • 您希望为负输入 (-123) 返回什么值?
  • @Jonathan:可能 OP 应该简单地更改函数签名以使用无符号类型。 :-)

标签: c algorithm recursion


【解决方案1】:

让我们更详细地看一下这个递归函数:

int sum (int a) {
    int f;

    if (a == 0)
        return f;

    f = (a% 10) + sum (a/10);
}

虽然您走在正确的轨道上并且您的想法总体上是正确的,但您的实际实现还是有些错误。首先,让我们看看这些行:

if (a == 0)
    return f;

a 达到零时终止递归的想法是正确的,但是你这样做的方式有点偏离。特别是,您返回整数 f 的值,但您从未初始化它。这意味着返回值是完全任意的。而不是写这个,我认为你可能打算写一些更接近

if (a == 0)
    return 0;

正确地说“如果数字为零,则其数字之和为零。”

同样,看看你的函数的最后一行:

f = (a% 10) + sum (a/10);

再一次,你的直觉是准确的:一个数字的数字之和由它的第一个数字之和和它的其余数字之和给出。但是,请注意,虽然您正确地计算 位数的总和,但您并没有正确地返回 位数的总和。事实上,如果你执行这段代码,你根本不会返回任何东西,所以函数的返回值是未指定的,因此是垃圾输出。要解决此问题,请考虑重写如下代码:

return (a % 10) + sum (a / 10);

这实际上是说要在这里交回你刚刚生成的值,而不是将其存储在一个局部变量中,该变量将在函数返回后立即清理。

我相信您以这种方式编写此函数的原因是您认为int f; 的值是通过函数调用传递的。不幸的是,事实并非如此。在编写递归函数时,函数的每个实例都完全独立于其他实例,并且在一个递归调用中可访问的局部变量在其他递归调用中不可访问。因此,即使每个递归调用都有自己的变量int f,这些变量都是完全相互独立的。价值不会通过它们传递。如果您想在递归函数之间传递值,最好的方法是使用递归调用的返回值,或者(如果必须)通过递归向下传递指向某个值的指针。

希望这会有所帮助!

【讨论】:

  • 是的,它有很大帮助,你得到了正确的观点,我认为 f 正在经历迭代......非常感谢
  • @Udit Gupta- 很高兴为您提供帮助!如果您认为这回答了您的问题,则应将答案标记为已接受,以便问题得到解决。
【解决方案2】:

当 a 为 0 时,您将返回一个未初始化的值(f 未初始化)。

改成:

if (a == 0)
        return 0;

你也忘记了函数末尾的返回:

return (a% 10) + sum (a/10);

强烈建议您始终使用标志 -Wall 进行编译,这会警告您这些错误。

【讨论】:

  • 更别提sum末尾没有return语句了。
  • @Chris:好点子,我在找到第一个错误后不再寻找错误,我会更新答案。
【解决方案3】:

您的递归函数将不计算任何内容,它要么返回未初始化的 int,要么不返回任何内容。您需要返回您在函数中所做的工作。

int sum (int a) {
  if (a == 0) {
    return 0;
  }
  return (a% 10) + sum(a/10);
}

【讨论】:

    【解决方案4】:
    return a == 0 ? 0 : ((a% 10) + sum (a/10));
    

    【讨论】:

      【解决方案5】:

      您只返回 f 是否为 0,但如果不是则不返回,这使您的返回值未定义。我假设你想做:

      int sum (int a) {
      
          int f;
      
          if (a == 0)
              return 0;
      
          f = (a % 10) + sum (a / 10);
      
          return f;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-14
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        • 2018-06-29
        • 2013-11-10
        • 2019-07-04
        • 2017-04-14
        相关资源
        最近更新 更多