Reputation: 95
I wrote this code that counts how many 1's there are in an integer using recursion. N has to be less than 9 digits. I can't seem to find what's wrong with my code and why it won't work. If anyone can give me a hint of where I went wrong I'd appreciate it.
#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;
}
Upvotes: 0
Views: 205
Reputation: 310950
For starters there is a typo
x == n%10;
You mean assignment instead of the comparison
x = n%10;
In these calls of the function
if (x == 1)
{
sum = sum + 1;
count_ones(n/10);
}
else
{
count_ones(n/10);
}
you are not using the returned values of the recursive calls
count_ones(n/10);
Moreover as the function parameter has the signed type int
then the user can pass to the function a negative number. In this case the function will return a wrong result.
Pay attention to that such restriction
else if(n > 999999999)
does not make a sense. The user can enter any number of the acceptable range of values for objects of the type int
.
The function can look the following way as it is shown in the demonstrative program below.
#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;
}
The program output is
2
2
Upvotes: -1
Reputation: 64682
Way too complicated.
Here's how to do it right:
int count_ones(int n)
{
return n? (n%10 == 1) + count_ones(n/10) : 0;
}
For completeness, here's an iterative (non-recursive) solution.
int count_ones(int n)
{
int total=0;
for(;n; n/=10, total += (n%10==1));
return total;
}
Upvotes: 0
Reputation: 18299
@Barmar's answer is giving you the idea of how to fix your approach. Here is an alternative one, which make the advantage of tail recursion which can be unrolled into a loop by the compiler. This approach is using accumulator (acc
) to count the ones, and will only return it once.
int count_ones_rec(int n, int acc)
{
if (n == 0)
return acc;
return count_ones_rec(n / 10, acc + (n % 10 == 1));
}
This can be wrapped in a function like:
int count_ones(int n)
{
/* additional checks on `n` if needed */
return count_ones_rec(n, 0);
}
Upvotes: 0
Reputation: 780842
You're not combining the current sum
with the result from the recursive call. So you're just counting the last digit, all the other counts are being discarded.
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);
}
}
Upvotes: 4