Home > OS >  How to check if a given number is a perfect number recursively in C
How to check if a given number is a perfect number recursively in C

Time:03-25

I have this HW about writing a recursive function in C that returns 0 or 1 based on if a given number is a perfect number or not.
A perfect number is a number that is equal to the sum of its divisors. For example, 6 is equal to (1 2 3), so it is a perfect number.
I've managed to write a recursive function that calculates the Sum of a given number's divisors, but the output is the sum of the divisors, not 0 or 1. I have zero idea how to write a recursive function that returns 0 or 1 and at the same time calculate the sum of divisors and do the comparison.

This is my code that outputs the sum of divisors :

#include<stdio.h>

int check(int n, int b ){
    
    if (n==1) {return(1);}
    if (b==1) {return(1);}
    
    else if ((n % b) ==0)  {
        return (b check(n,(b-1)));
    }
    else
     return(check(n,(b-1)));
    }

 void main() {

    int n,res,b; 
    scanf("%d",&n);
    if (n % 2==0) {b=n/2;} else {b=(n/2) 1;} 
    res=check(n, b);
    printf("%d est un nombre %d",n,res);

}

CodePudding user response:

Notice that 1 is not a perfect number. The sum of all divisors when deciding if a number is perfect excludes the number itself. 0 is also not perfect, since perfect numbers have to be positive.

if (n < 2) return 0;

Assume the accumulated sum of divisors is passed into the function. Then, when you reach the stopping point, you return whether the sum is equal the number. To make this logic simple, the stopping point can be when your candidate divisor reaches 0.

if (b == 0) return sum == n;

Your recursive call will now check to see if your candidate divisor should be added to the sum.

assert(b > 0);
if ((n % b) == 0) sum  = b;
return check(n, b-1, sum);

Implemented this way, the function becomes tail recursive. This would allow your recursive function to be optimized into a simple loop by a compiler that supports this optimization.

The initial call to your function would pass 0 in for the initial sum.

answer = check(n, n/2, 0);

In my own code, I would be tempted to define a helper function that only takes the single argument.

int check_if_perfect(int n) { return check(n, n/2, 0); }

This way, the caller wouldn't need to worry about the other arguments.

answer = check_if_perfect(n);
  • Related