简体   繁体   中英

Distinguishing Even and Odd Numbers with Recursion

I have a problem that I'm having a tough time figuring out, figured I would see if someone could point me in the right direction.

I am writing a recursive method(s) that takes an int for it's parameter, then displays all squared values of the odd numbers (top down) then all squared values of the even numbers (again top down)

Eg 6 would output

25, 9, 1, 36, 16, 4

My approach would be to have 3 methods. One int recursiveOdd(int num) that would calculate and output to console the squared values of odd. One int recursiveEven(int num) that would calculate and output to console the squared values of even. And one method void passToRecursive(int num) that simply takes the number and calls the other two methods.

My question is how do I approach the first method, finding the highest odd number then finding the highest even number without using a loop.

Obviously, the max number is going to be whatever int was passed from main . I simply can't think of how I would find the highest odd w/oa loop.

If the given number is N , then the highest even number is found by taking half, truncating, and multiplying by 2:

(N / 2) * 2

The highest odd number is a little trickier: subtract 1, find the highest even number for that , and then add 1:

((N-1) / 2) * 2 + 1

That gives you your two numbers (truncate / floor as needed). Now, for the recursion: you need your base case (finishing condition) and your recursion case.

Base case: if N <= 0 , return without printing anything. Recursion: print N*N; recur with the value (N-2).

By the way, note that the recursive routine is identical for the odd and even cases: you need only one recursive routine. Call it twice from the passTo routine, once each with the odd and even numbers you found at the start.

Finally, please consider changing the name passToRecursive . It's a little misleading, since it is not, itself, a recursive routine; it's merely a handler. Someone calling it doesn't care that it has recursive subroutines. Instead, give it a name descriptive of what it does.

If you are looking for poiner in the right direction, try transforming this into C++

function oddSquare(int value) {
  if (value mod 2 == 0) value --;
  if (value > 0) {  /* Stop when we get too small */
    print value * value;
    oddSquare(--value); /* Decrement to next lower value and recurse
  }
}

We beginners should help each other.:)

I can suggest a solution that is based on using a static variable inside the recursive function.

Here is a demonstrative program.

#include <iostream>

void OddEvenSquares( unsigned int n )
{
    static unsigned long long int even;

    if ( n != 0 )
    {
        if ( n % 2 )
        {
            std::cout << static_cast<unsigned long long int>( n ) * n << ' ';
            OddEvenSquares( n - 1 );
        }
        else
        {
            even += 2;
            OddEvenSquares( n - 1 );
            std::cout << even * even << ' ';
            even -= 2;
        }
    }        
}

int main()
{
    const unsigned int N = 10;

    for ( unsigned int i = 1; i <= N; i++ )
    {
        OddEvenSquares( i );
        std::cout << std::endl;
    }        
}    

Its output is

1 
1 4 
9 1 4 
9 1 16 4 
25 9 1 16 4 
25 9 1 36 16 4 
49 25 9 1 36 16 4 
49 25 9 1 64 36 16 4 
81 49 25 9 1 64 36 16 4 
81 49 25 9 1 100 64 36 16 4 

Or the function can have a second parameter with a default argument.

For example

#include <iostream>

std::ostream & OddEvenSquares( unsigned int n, std::ostream &os = std::cout )
{
    static unsigned long long int even;

    if ( n != 0 )
    {        
        if ( n % 2 )
        {
            std::cout << static_cast<unsigned long long int>( n ) * n << ' ';
            OddEvenSquares( n - 1, os );
        }
        else
        {
            even += 2;
            OddEvenSquares( n - 1, os );
            os << even * even << ' ';
            even -= 2;
        }
    }

    return os;
}

int main()
{
    const unsigned int N = 10;

    for ( unsigned int i = 1; i <= N; i++ )
    {
        OddEvenSquares( i ) << std::endl;
    }        
}    

The program output will be the same as shown above.

As for your approach when there are two separate recursive functions for odd and even numbers then function passToRecursive can look the following way

void passToRecursive( int num )
{
    if ( num > 0 )
    { 
        int odd, even;

        if ( num % 2 )
        {
            odd = num;
            even = odd - 1;
        }
        else
        {
            even = num;
            odd = even - 1;
        }

        recursiveOdd( odd );
        recursiveEven( even );
    }
}

You may change the inner if-else statement to the conditional operator. For example

void passToRecursive( int num )
{
    if ( num > 0 )
    { 
        int odd, even;

        num % 2 ? ( odd  = num, even = odd  - 1 ) 
                : ( even = num, odd  = even - 1 );

        recursiveOdd( odd );
        recursiveEven( even );
    }
}

In fact you even do not need to define two recursive functions because their bodies can be the same.

So function passToRecursive can look like

void passToRecursive( int num )
{
    if ( num > 0 )
    { 
        int odd, even;

        num % 2 ? ( odd  = num, even = odd  - 1 ) 
                : ( even = num, odd  = even - 1 );

        recursiveSquares( odd );
        recursiveSquares( even );
    }
}

Pay attention to this statement

std::cout << static_cast<unsigned long long int>( n ) * n << ' ';

The product of two integers can be greater than the maximum value that can be stored in type int or unsigned int . So you need to use some larger integer type as for example long long int or unsigned long long int for the product.

As usually my answer is the best.:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM