【问题标题】:using recursion to calculate total digits使用递归计算总位数
【发布时间】:2021-05-16 14:36:13
【问题描述】:

我编写了这段代码,它使用递归计算整数中有多少个 1。 N 必须小于 9 位。我似乎找不到我的代码有什么问题以及为什么它不起作用。如果有人能提示我哪里出错了,我将不胜感激。

#include <stdio.h>
#include <assert.h>

int count_ones(int n);

int main()
{
    assert(count_ones(1001)==2);
}

int count_ones(int n)
{   
    int sum = 0;
    int x;
    if(n == 0)
    {
        return sum;
    }
    else if(n > 999999999)
    {
        return sum;
    }
    else if(n <= 999999999)
    {
        x == n%10;
        if (x == 1)
        {
        sum = sum + 1;
        count_ones(n/10);
        }
        else
        {
        count_ones(n/10);  
        }
    }
    return sum;
}

【问题讨论】:

  • 请使用您的调试器。问题是您没有添加递归调用的结果。
  • x == n % 10; 是干什么用的?

标签: c recursion counting function-definition


【解决方案1】:

您没有将当前的sum 与递归调用的结果结合起来。所以你只计算最后一个数字,所有其他的计数都被丢弃了。

int count_ones(int n) {
    if (n == 0 || n > 999999999) {
        return 0;
    } else if (n % 10 == 1) {
        return 1 + count_ones(n / 10);
    } else {
        return count_ones(n / 10);
    }
}

【讨论】:

  • 为了进一步优化,可以将检查n &gt; 999999999移出函数,这样就不会为每个递归调用执行,因为它只需要一次
【解决方案2】:

@Barmar 的回答是让您了解如何解决您的方法。这是一种替代方法,它利用 tail recursion 的优势,可以由编译器展开成循环。这种方法是使用累加器(acc)来计数,并且只会返回一次。

int count_ones_rec(int n, int acc)
{
    if (n == 0)
        return acc;
    return count_ones_rec(n / 10, acc + (n % 10 == 1));
}

这可以包装在一个函数中,例如:

int count_ones(int n)
{
    /* additional checks on `n` if needed */
    return count_ones_rec(n, 0);
}

【讨论】:

    【解决方案3】:

    太复杂了。

    下面是正确的做法:

    int count_ones(int n)
    {
        return n? (n%10 == 1) + count_ones(n/10) : 0;
    }
    

    为了完整起见,这里是一个迭代(非递归)解决方案。

    int count_ones(int n)
    {
        int total=0;
        for(;n; n/=10, total += (n%10==1));
        return total;
    }
    

    【讨论】:

      【解决方案4】:

      对于初学者来说有一个错字

      x == n%10;
      

      你的意思是赋值而不是比较

      x = n%10;
      

      在函数的这些调用中

          if (x == 1)
          {
          sum = sum + 1;
          count_ones(n/10);
          }
          else
          {
          count_ones(n/10);  
          }
      

      您没有使用递归调用的返回值

      count_ones(n/10);
      

      此外,由于函数参数具有签名类型int,因此用户可以将负数传递给函数。在这种情况下,函数将返回错误的结果。

      注意这种限制

      else if(n > 999999999)
      

      没有意义。用户可以为int 类型的对象输入任意数量的可接受值范围。

      该函数可以如下面的演示程序所示。

      #include <stdio.h>
      
      size_t count_ones( int n )
      {
          const int Base = 10;
          
          return n == 0 ? 0 : ( n % Base == ( n < 0 ? -1 : 1 ) ) + count_ones( n / Base ); 
      }
      
      int main(void) 
      {
          printf( "%zu\n", count_ones( -11 ) );
          printf( "%zu\n", count_ones( 11 ) );
          
          return 0;
      }
      

      程序输出是

      2
      2
      

      【讨论】:

      • 函数以return sum;结尾,所以没有未定义的行为。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      相关资源
      最近更新 更多