Recursive function In C - 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;

Related

recursive Function, to find even or odd digits inside given number

Basically, its printing only one instance when it happens, and i don't understand why, maybe has something to do with the code reseting every time and starting the variable at 0 again, and i got another question if someone can help me with, i have to return both values when its odd and even, like how many digits are even and odd at the same time, i'm having a little trouble figuring out how to do it
#include <stdio.h>
int digits(int n)
// function that checks if the given value is odd or even, and then add
// + 1 if it's even, or odd, it's supposed to return the value of the quantity
// of digits of the number given by the main function
{
int r;
int odd = 0;
int even = 0;
r = n % 10;
if (r % 2 == 0) // check if given number is even
{
even = even + 1;
}
if (r % 2 != 0) // check if its odd
{
odd = odd + 1;
}
if (n != 0) {
digits(n / 10); // supposed to reset function if n!=0 dividing
// it by 10
}
if (n == 0) { return odd; }
}
int
main() // main function that sends a number to the recursive function
{
int n;
printf("type number in:\n ");
scanf("%d", &n);
printf("%d\n", digits(n));
}
odd and even variables are local in your code, so they are initialized by zero every time.
I think they should be declared at caller of the recursive function, or be declared as global variables.
#include <stdio.h>
void digits(int n, int *even, int *odd)//function
{
int r;
r = n % 10;
if (r % 2 == 0)//check if given number is even
{
*even = *even + 1;
}
else //otherwise, its odd
{
*odd = *odd + 1;
}
n /= 10;
if (n != 0)
{
digits(n, even, odd);//supposed to reset function if n!=0 dividing it by 10
}
}
int main()
{
int n, even = 0, odd = 0;
printf("type number in:\n ");
scanf("%d", &n);
digits(n, &even, &odd);
printf("even: %d\n", even);
printf("odd: %d\n", odd);
return 0;
}
Maybe I found the problem you are facing. You you initialized you odd and even variable as zero. every time you call the function it redeclares their value to zero again. You can use pointer caller or use those as your global variable so that every time they don't repeat their initial values again.
Implementing a function that counts the number of odd and even digits in a number, is not to be done using recursive. That is simply a wrong design choice.
But I assume that it's part of your assignment to use recursion so ... okay.
You want a function that can return two values. Well, in C you can't!! C only allows one return value. So you need another approach. The typical solution is to pass pointers to variables where the result is to be stored.
Here is the code:
void count_odd_even(const int n, int *even, int *odd)
{
if (n == 0) return;
if (((n % 10) % 2) == 1)
{
*odd += 1;
}
else
{
*even += 1;
}
count_odd_even(n/10, even, odd);
}
And call it like
int odd = 0;
int even = 0;
count_odd_even(1234567, &even, &odd);

using recursion to calculate total digits

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

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

Function that returns the sum of the number of dividers without remainder of a number, C

I could easily print what I wanted in a loop, but I'm new to functions and I need to save or return the sum of the dividers that have no remainder to a number which is an input of the user.
Example:
Input - 6
Output - 1+2+3=6
How I started:
int NumberOfDividers(int number)
{
int i,num, count = 0;
num = number;
for ( i = 0; i < num; i++)
{
if ((num % i) == 0) //so now I know i is one of the dividers i want to save.
}
}
So if i is one of the dividers I want, how can I save it into a variable? Or an array?
To return the sum of the proper divisors, do:
int sum_of_proper_divisors (int number)
{
int sum = 0;
int i;
for (i = 1; i < number; i++)
{
if ((number % i) == 0)
sum += i;
}
return sum;
}
You just need to use the return keyword to return the value.
You can do this way...
//other headers as you need
#include<string.h>//this header is for memset
int dividers[1000];//global array
int currPos;//global variable
int NumberOfDividers(int number)
{
int i,num, count = 0;
num = number;
for ( i = 1; i < num; i++)//you should start counting from 1 otherwise you will get floating point exception
{
if ((num % i) == 0)
{
dividers[currPos]=i;//putting the dividers in the array
currPos++;//updating the pivot where the next dividers will stay
}
}
return 0;
}
int main()
{
memset(dividers,0,sizeof(dividers));//initializing the array
currPos=0;//initializing the variable to point at the start of the array
NumberOfDividers(6);
int i;
int sum=0;
for(i=0;i<currPos;i++)
{
printf("%d",dividers[i]);
sum+=dividers[i];
if(i!=currPos-1)
{
printf("+");
}
}
printf("=%d\n",sum);
return 0;
}
As this task looked fun to do, did not want to take away the coding experience. Instead laid out a sample algorithm that should code in C fairly directly.
Pseudo-code
int *NumberOfDividers(int number)
find isqrt(number) --> sqrt_number
sqrt_number*2 + 2 --> max_array_count
allocate int[] with max_array_count elements
validate allocation
starting at divisor = 1, in a loop ...
quotient = number/divisor
remainder = number%divisor
if (remainder == 0)
add divisor to list
if (divisor != quotient) add quotient to list
if (divisor >= quotient) quit loop
divisor++
append 0 to list to indicate the end
shrink array to needed size if desired
validate shrink result
return array pointer.
Notice the loop does at most sqrt(number) iterations, so a reasonable upper bound of the needed array size can be calculated before using any divisors.
Also see How many positive integers are factors of a given number? for more advanced ideas.
You can see an another way to do this. This will work very fast for a vast amount of data. Here is my way and you can follow this to find this in a fastest way to find the sum of factors of a number. Here is my code:
int number_of_divisor(int n)
{
int sum_of_factors=0;
sum_of_factors+=1;//as 1 is factor of all num
//sum_of_factors+=n;//n will always a factor of n
for(int i = 2; i * i <= n; ++i)
{
if(n % i == 0)
{
sum_of_factors+=i;
if(i * i != n)
sum_of_factors+=(n/i);
}
}
return sum_of_factors;
}
if your input is long then change all int by long.
Thank you.

How to check whether a no is factorial or not?

I have a problem, then given some input number n, we have to check whether the no is factorial of some other no or not.
INPUT 24, OUTPUT true
INPUT 25, OUTPUT false
I have written the following program for it:-
int factorial(int num1)
{
if(num1 > 1)
{
return num1* factorial(num1-1) ;
}
else
{
return 1 ;
}
}
int is_factorial(int num2)
{
int fact = 0 ;
int i = 0 ;
while(fact < num2)
{
fact = factorial(i) ;
i++ ;
}
if(fact == num2)
{
return 0 ;
}
else
{
return -1;
}
}
Both these functions, seem to work correctly.
When we supply them for large inputs repeatedly, then the is_factorial will be repeatedly calling factorial which will be really a waste of time.
I have also tried maintaining a table for factorials
So, my question, is there some more efficient way to check whether a number is factorial or not?
It is wasteful calculating factorials continuously like that since you're duplicating the work done in x! when you do (x+1)!, (x+2)! and so on.
One approach is to maintain a list of factorials within a given range (such as all 64-bit unsigned factorials) and just compare it with that. Given how fast factorials increase in value, that list won't be very big. In fact, here's a C meta-program that actually generates the function for you:
#include <stdio.h>
int main (void) {
unsigned long long last = 1ULL, current = 2ULL, mult = 2ULL;
size_t szOut;
puts ("int isFactorial (unsigned long long num) {");
puts (" static const unsigned long long arr[] = {");
szOut = printf (" %lluULL,", last);
while (current / mult == last) {
if (szOut > 50)
szOut = printf ("\n ") - 1;
szOut += printf (" %lluULL,", current);
last = current;
current *= ++mult;
}
puts ("\n };");
puts (" static const size_t len = sizeof (arr) / sizeof (*arr);");
puts (" for (size_t idx = 0; idx < len; idx++)");
puts (" if (arr[idx] == num)");
puts (" return 1;");
puts (" return 0;");
puts ("}");
return 0;
}
When you run that, you get the function:
int isFactorial (unsigned long long num) {
static const unsigned long long arr[] = {
1ULL, 2ULL, 6ULL, 24ULL, 120ULL, 720ULL, 5040ULL,
40320ULL, 362880ULL, 3628800ULL, 39916800ULL,
479001600ULL, 6227020800ULL, 87178291200ULL,
1307674368000ULL, 20922789888000ULL, 355687428096000ULL,
6402373705728000ULL, 121645100408832000ULL,
2432902008176640000ULL,
};
static const size_t len = sizeof (arr) / sizeof (*arr);
for (size_t idx = 0; idx < len; idx++)
if (arr[idx] == num)
return 1;
return 0;
}
which is quite short and efficient, even for the 64-bit factorials.
If you're after a purely programmatic method (with no lookup tables), you can use the property that a factorial number is:
1 x 2 x 3 x 4 x ... x (n-1) x n
for some value of n.
Hence you can simply start dividing your test number by 2, then 3 then 4 and so on. One of two things will happen.
First, you may get a non-integral result in which case it wasn't a factorial.
Second, you may end up with 1 from the division, in which case it was a factorial.
Assuming your divisions are integral, the following code would be a good starting point:
int isFactorial (unsigned long long num) {
unsigned long long currDiv = 2ULL;
while (num != 1ULL) {
if ((num % currDiv) != 0)
return 0;
num /= currDiv;
currDiv++;
}
return 1;
}
However, for efficiency, the best option is probably the first one. Move the cost of calculation to the build phase rather than at runtime. This is a standard trick in cases where the cost of calculation is significant compared to a table lookup.
You could even make it even mode efficient by using a binary search of the lookup table but that's possibly not necessary given there are only twenty elements in it.
If the number is a factorial, then its factors are 1..n for some n.
Assuming n is an integer variable, we can do the following :
int findFactNum(int test){
for(int i=1, int sum=1; sum <= test; i++){
sum *= i; //Increment factorial number
if(sum == test)
return i; //Factorial of i
}
return 0; // factorial not found
}
now pass the number 24 to this function block and it should work. This function returns the number whose factorial you just passed.
You can speed up at least half of the cases by making a simple check if the number is odd or even (use %2). No odd number (barring 1) can be the factorial of any other number
#include<stdio.h>
main()
{
float i,a;
scanf("%f",&a);
for(i=2;a>1;i++)
a/=i;
if(a==1)
printf("it is a factorial");
else
printf("not a factorial");
}
You can create an array which contains factorial list:
like in the code below I created an array containing factorials up to 20.
now you just have to input the number and check whether it is there in the array or not..
#include <stdio.h>
int main()
{
int b[19];
int i, j = 0;
int k, l;
/*writing factorials*/
for (i = 0; i <= 19; i++) {
k = i + 1;
b[i] = factorial(k);
}
printf("enter a number\n");
scanf("%d", &l);
for (j = 0; j <= 19; j++) {
if (l == b[j]) {
printf("given number is a factorial of %d\n", j + 1);
}
if (j == 19 && l != b[j]) {
printf("given number is not a factorial number\n");
}
}
}
int factorial(int a)
{
int i;
int facto = 1;
for (i = 1; i <= a; i++) {
facto = facto * i;
}
return facto;
}
public long generateFactorial(int num){
if(num==0 || num==1){
return 1;
} else{
return num*generateFactorial(num-1);
}
}
public int getOriginalNum(long num){
List<Integer> factors=new LinkedList<>(); //This is list of all factors of num
List<Integer> factors2=new LinkedList<>(); //List of all Factorial factors for eg: (1,2,3,4,5) for 120 (=5!)
int origin=1; //number representing the root of Factorial value ( for eg origin=5 if num=120)
for(int i=1;i<=num;i++){
if(num%i==0){
factors.add(i); //it will add all factors of num including 1 and num
}
}
/*
* amoong "factors" we need to find "Factorial factors for eg: (1,2,3,4,5) for 120"
* for that create new list factors2
* */
for (int i=1;i<factors.size();i++) {
if((factors.get(i))-(factors.get(i-1))==1){
/*
* 120 = 5! =5*4*3*2*1*1 (1!=1 and 0!=1 ..hence 2 times 1)
* 720 = 6! =6*5*4*3*2*1*1
* 5040 = 7! = 7*6*5*4*3*2*1*1
* 3628800 = 10! =10*9*8*7*6*5*4*3*2*1*1
* ... and so on
*
* in all cases any 2 succeding factors inf list having diff=1
* for eg: for 5 : (5-4=1)(4-3=1)(3-2=1)(2-1=1)(1-0=1) Hence difference=1 in each case
* */
factors2.add(i); //in such case add factors from 1st list " factors " to " factors2"
} else break;
//else if(this diff>1) it is not factorial number hence break
//Now last element in the list is largest num and ROOT of Factorial
}
for(Integer integer:factors2){
System.out.print(" "+integer);
}
System.out.println();
if(generateFactorial(factors2.get(factors2.size()-1))==num){ //last element is at "factors2.size()-1"
origin=factors2.get(factors2.size()-1);
}
return origin;
/*
* Above logic works only for 5! but not other numbers ??
* */
}

Resources