使用递归计算总位数

问题描述

我写了这段代码,它使用递归计算一个整数中有多少个 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;
}

解决方法

您没有将当前的 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);
    }
}
,

太复杂了。

正确的做法如下:

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;
}
,

@Barmar 的回答让您知道如何解决您的方法。这是另一种方法,它利用了尾递归的优势,可以由编译器展开到循环中。这种方法是使用累加器 (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);
}
,

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

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