using recursion to calculate total digits - c

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

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

#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);
}

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

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

Related

Next Prime number function problem when I use a recursive function

I have a problem with a recursive function. The function must return the next prime number.
As parameter I give a number an it must return the number if is prime, or the next prime number.
The function works fine in almost cases, when I comment the recursion it shows a list of numbers from one to hundred and allocate the primes. The rest return O.
But when I insert the recursive in some cases shows a next prime that is not prime, case of 35 and 95 for example.
when I put 4 it show the next prime that is 7.
but when it reaches 32 it shows 35 that was not correct. It should shows 37.
I don't know were the problem is.
The code is:
#include <stdio.h>
#include <unistd.h>
int ft_find_next_prime(int nb)
{
int i;
int z;
i = nb - 1;
z = nb;
while (i > 1)
{
if ((z % i) == 0)
{
//return (0);
ft_find_next_prime(++z);
}
else
i--;
}
return (z);
}
int main(void)
{
int i;
i = 1;
printf("\n\tNUMERO\t---\tSIGIENTE PRIMO\n");
printf("-----------------------------------------------------\n");
while (i <= 100)
{
printf("\t%i\t---\t%i\n", i, ft_find_next_prime(i));
i++;
}
return (0);
}
Thanks so much in advance.
The only thing missing in the recursive code is the return keyword, or an assignment of the variable z. The reeason is that the z passed into parameter is a copy, not the original z variable.
int ft_find_next_prime(int nb)
{
int i;
int z;
i = nb - 1;
z = nb;
while (i > 1)
{
if ((z % i) == 0)
{
//return (0);
return ft_find_next_prime(++z);
// or : z = ft_find_next_prime(++z);
}
else
i--;
}
return (z);
}

Elaborate a function parameter as static variable

I was wondering how to make a function consider a given parameter as a static variable. For example, i tried, without success, to generate hailstone numbers:
#include<stdio.h>
int hailstone(int);
int n; /* n is an extern variable*/
int main(){
hailstone(n);
return 0;
}
int hailstone(int n){
static int m = n; /*not possible because n is not constant*/
if(m % 2 == 0 && m != 1)
hailstone(m /= 2);
else if(m != 1)
hailstone((m *= 3) + 1);
else
exit(0); /*Is the use of exit() correct, in this case?*/
return 0;
}
I would like to use a static variable to elaborate n. Otherwise, each recursive call would operate on the whole parameter n, thus going on endless, never reaching the case base.
Few questions:
Does this idea represent a feasible approach to the problem?
Does this idea represent a reasonable/effective approach to the problem?
Is exit(0) used correctly, in a similar case?
You don't need a static variable for this. Just pass in the new value to operate on and use that. Also, the value 1 is your base case, so check for that to stop the recursion, and print the value of n so you can actually see what's going on.
void hailstone(int n){
printf("n=%d\n", n);
if(n % 2 == 0 && n > 1) {
hailstone(n/2);
} else if(n > 1) {
hailstone((n*3) + 1);
}
}
Given that this function could go on for quite a few iterations, a recursive solution could end up causing a stack overflow. Better to go with an iterative solution:
void hailstone(int n){
while (n > 1) {
printf("n=%d\n", n);
if(n % 2 == 0) {
n = n/2;
} else {
n = (n*3) + 1;
}
}
}
Here's the recursive algorithm for hailstorm, there's no need for static
#include <assert.h>
#include <stdio.h>
void hailstone(unsigned int n)
{
assert(n>0);
printf("%u\n", n);
if ( n == 1 )
return;
if( n & 1 ) {
hailstone(3*n + 1);
}
else {
hailstone(n >> 1);
}
}
int main() {
hailstone(5);
}

time limit exceeded error in a simple function C

I'm making a function that reverses numbers less than 100000000. For example, if the input is 1234 then it should return 4321. But I am getting time limit exceeded TLE, I have made break points of my for loops but don't know why. Can you tell me what's wrong with this code?
int reverse(int n){
int i, j=1, d[100000000]={0}, rev=0;
for(i=10; ;i*10){
if(n%i==n){
d[j]=(n%i)/(i/10);
break;
}
d[j++]=(n%i)/(i/10);
}
for(j=1; ;j++){
rev+=(d[j]*(i/10));
i/=10;
if(i==10)
break;
}
return rev;
}
int main(){
printf("%d",reverse(321));
return 0;
}
Use basic knowledge of how numbers work: place value. If you use the % operator to extract the least significant digit from the number, you can build up the reversed number. Try this:
int reverse(int n)
{
int result = 0;
while ( n > 0 )
{
result = result * 10 + (n % 10);
n /= 10;
}
return result;
}

Recursion with Max Integer

I am writing a program to calculate the factorial of a number. I am using recursion to solve this problem. The problem I am running into is that once I reach number 13, it will throw garbage numbers because of INT's limit. What I want to do is implement a way to catch the error when it happens (without hard cording that at x=13 it has to stop, but rather by the output). This is my attempt:
#include <stdio.h>
int factorial( int n)
{
printf("Processing factorial( %d )\n", n);
if (n <= 1)
{
printf("Reached base case, returning...\n");
return 1;
}
else
{
int counter = n * factorial(n-1); //Recursion to multiply the lesser numbers
printf("Receiving results of factorial( %d ) = %d * %d! = %d\n", n, n, (n-1), counter);
if( counter/n != factorial(n-2) ) //my attempt at catching the wrong output
{
printf("This factorial is too high for this program ");
return factorial(n-1);
}
return counter;
printf("Doing recursion by calling factorial (%d -1)\n", n);
}
}
int main()
{
factorial(15);
}
The problem with this is that the program now never terminates. It keeps on looping and throwing me random results.
Since I cannot answer my own question, I will edit with my solution:
int jFactorial(int n)
{
if (n <= 1)
{
return 1;
}
else
{
int counter = n *jFactorial(n-1);
return counter;
}
}
void check( int n)
{
int x = 1;
for(x = 1; x < n+1; x++)
{
int result = jFactorial(x);
int prev = jFactorial(x-1);
if (((result/x) != prev) || result == 0 )
{
printf("The number %d makes function overflow \n", x);
}
else
{
printf("Result for %d is %d \n", x, result);
}
}
}
A better way to do it:
if (n <= 1) {
return 1;
} else {
int prev_fact = factorial(n - 1);
if (INT_MAX / prev_fact < n) { /* prev_fact * n will overflow */
printf("Result too big");
return prev_fact;
} else {
return prev_fact * n;
}
}
Uses a more accurate check (I hope) for whether the multiplication will overflow, and doesn't add any more calls to factorial.
Update
After looking more closely, turns out I missed the fact that gmp is also implemented for C. Here is the solution in C
I've been able to run it on my macbook pro, using homebrew to install gmp (brew isntall gmp)
#include <gmp.h>
#include <stdio.h>
void factorial(mpz_t ret, unsigned n) {
if (n <= 1) {
mpz_set_ui(ret, 1);//Set the value to 1
} else {
//multiply (n-1)! with n
mpz_t ret_intermediate;
mpz_init (ret_intermediate);//Initializes to zero
factorial(ret_intermediate, n-1);
mpz_mul_ui(ret, ret_intermediate, n);
}
return;
}
int main(){
mpz_t result;
mpz_init (result);
factorial(result, 100);
char * str_result = mpz_get_str(NULL, 10, result);
printf("%s\n", str_result);
return 0;
}
Original Answer
After quick googling, I found the following solution. Note this is a C++ solution. I briefly descirbe how you could do the same thing in ANSI C at the bottom.
Big numbers library in c++
https://gmplib.org/ This c++ library can work on numbers arbitrarily large.
Checkout https://gmplib.org/manual/C_002b_002b-Interface-General.html
The whole code could look something like....
#include <gmpxx.h>
#include <iostream>
mpz_class factorial(unsigned n) {
if (n <= 1) return mpz_class(1);
return mpz_class(n) * factorial(n-1);
}
int main(){
mpz_class result = factorial(100);
std::string str_result = result.get_str();
std::cout << str_result << std::endl;
return 0;
}
The ANSI C Version
You could implement the same thing using ansi C, with a structure to hold expanding list of numbers(using linked-list or any other expandable arraylist containers), and you'd only need to implement three methods... initialize, multiply and convert to string.

Recursive function In C

I have a recursive function and I want to count the number of zeros in it, how do I use a constant to count the zero and not allowing to reset.
int countZeros(int num)
{
int count = 0;
if (num > 0)
{
if (num % 10 == 0)
count++;
return(countZeros(num / 10));
}
if (num <= 0)
return count;
}
For my code, my count will reset once my return function is called. Is there any way to prevent this from happening? I have to return the value back to my main function and display from there.
case 9:
printf("Enter a number: ");
scanf("%d", &recursion);
printf("number of zeros = %d",countZeros(recursion));
break;
Try this code:
int countZeros(int num)
{
if (num > 0 && num % 10 == 0)
return(countZeros(num / 10)+1);
else
return 0;
}
It will work in the same way, only note that if your num is negative (but still with zeroes, like -100, it will return 0).
In order to work with negative numbers, use this:
int countZeros(int num)
{
if (num !=0 && num % 10 == 0)
return (countZeros(num / 10)+1);
else
return 0;
}
Make your int static:
static int count = 0;
Here is a sample run.
Pointers will work as well:
#include <stdio.h>
int countZeros(int num, int * count)
{
if (num > 0)
{
if (num % 10 == 0)
(*count)++;
return(countZeros(num / 10,count));
}
if (num <= 0)
return *count;
}
int main(void)
{
int count = 0;
printf("Count = %d",countZeros(1000,&count) );
return 0;
}
Avoid static variables, they are evil, for multiple reasons...
The only algorithm that works, and doesn't just count the trailing zeros, is ring0's answer, but please, local variables are free, and explicit code helps not only the reader, but is much more maintainable.
Run it here.
#include <stdio.h>
int main(void)
{
printf("Count = %d\n", countZeros( 10100) );
printf("Count = %d\n", countZeros(-10010) );
return 0;
}
int countZeros(int num)
{
// Final stop
if (num == 0 )
return 0;
// Recursion for numbers to the left
int count = countZeros(num / 10);
// Increase count if current unit is 0
if (num % 10 == 0)
count++;
return count;
}
Explanation:
For the recursion, you need a converging process and a stop condition.
The first IF is the base case. Dividing 3 (or -3 for that matter) by 10 will always end up being 0. This is what ends the recursion (stop condition).
The second and last blocks are interchangeable. If the rightmost number is 0, you increase the counter, but then, you also need to add the count result from all the numbers to the left. This is done by seeding it only what you didn't count, hence the division by 10 (to converge).
Both division and modulo works the same for negative and positive numbers, so you keep the behavior for both ends of the integer range.
Without any more variable
int countZeros(int n) {
return n ? (n % 10 ? 0:1)+countZeros(n/10) : 0;
}
countZeros works also with negative numbers.
Example
printf("%d\n", count( 10001)); // prints "3"
printf("%d\n", count(-10001)); // prints "3"
use static variable.
static int count = 0;

Resources