2

The following is a function that is meant to return the reverse of a number using recursion. However, it only returns the last digit of the number. I'd like to know why and how to fix it?

int rev(int number)
{
      int revNum=0, sum=100;

      if(number<=9) return(number);
      else if(number>0) 
      {
           return(rev(number/10)+revNum);
           revNum=(number%10)*sum; sum=sum/10;

      }
}

Thank you!!!

8
  • 1
    what do you mean reverse the number? as for the code, everything after that return statement has no meaning Commented Jul 18, 2013 at 6:19
  • if(number<=9) else if(number>0) what is that??There is something between 0-9 which is ready to satisfy both condition. Commented Jul 18, 2013 at 6:26
  • he wants to reverse the digits, so: 1234 becomes 4321 Commented Jul 18, 2013 at 6:28
  • BTW: the last line revNum=(number%10)... will be never reached Commented Jul 18, 2013 at 6:31
  • the problem is mostly because sum is not preserved across recursion, among other things Commented Jul 18, 2013 at 6:40

8 Answers 8

12

Here's some working code:

int rev (int number){
    int base = 1;

    while (number / (base * 10)){/*
        * This calculates the base of the number
        * ie number = 435
        *    base   = 100
        */
        base *= 10;
    }

    if (number <= 9){
        return number;
    } else if (number >= 10){ // notice different expression
        int revNum = (number % 10) * base; // this was out of order
        return rev (number / 10) + revNum;
    }
}

The main reason your code couldn't work, other than what I commented above, is that sum isn't preserved within the calls. This is a common problem in making recursive functions.

To remedy this, the "base" is calculated each function call, instead of having a fixed value. This also a bit better because it allows larger numbers to be passed, instead of ones not bigger than 100 (another limit of the code you've chosen).

Another implementation is to base the base as a second parameter, so that it doesn't have to be recalculated every function call. This can, however, be easily remedied by a simple macro. The call may be :

int rev_number (int number, int base){ .. }

But a can be conveniently placed in a macro (or other function call):

#define rev(num) rev_number (number, 0)

This is a little more efficient, but the difference may or may not be important.

Sign up to request clarification or add additional context in comments.

5 Comments

@Jost it's more contained but less efficient, since the base is calculated every call.
@Taylor_Flores Yeah, but to be honest - we are dealing with recursive functions - the function calls are expensive (and multiple parameters don't make it better ;-) ). I think it is only for learning purposes: transform a function into a recursive function or vice versa.
Thank you very much, the solution is crystal clear; except I don't understand what while(number/(base*10)) does?
@MichaelFerashireSilva The value of number/base*10 should be 1 for the loop to execute
The while loop could be moved into the else if statement to make things slightly quicker when number is 0-9. In other words, there isn't much point of attempting to calculate a base when the number is 0-9.
9

This is the solution.

Call below function as reverse (number, 0);

int reverse(long int n, long int rev) {
    if(n == 0)
        return rev; 
    return reverse(n / 10, rev * 10 + n % 10);
}

1 Comment

One int divide by 10 and one int multiply by 10 per number of digits: most efficient.
7
int rev(int num){
    return num < 10 ? num : (num % 10) * pow(10, (int)log10(num)) + rev(num/10);
}

And it's done in one line.

9 Comments

wow it works, although I'm not sure how you utilized pow and log to make it work?
@MichaelFerashireSilva well (num % 10) is last digit so in order it to be first you have to multiply it with a value which starts with an 1, continues with 0 and has exactly as many digits as your num. So basicly if your number is 123456 , (num % 10) * pow(10, (int)log10(num)) computes first time 600000' then '50000' and so on. An when the last value which is less then 10` is returned it starts adding the results.
@AlexandruBarbarosie why does being in one line make it better? a) it's less readable. b) it's not even recursive
@TaylorFlores a) the program will occupy less hard disc memory and will use less operating memory b) it is recursion since i'm calling rev(num/10) over and over again.
@TaylorFlores you know... I checked both of them and in terms of speed, your is a little faster then mine. Approximately 1.25 times. I think it is because of pow and log10 being computed slowly. So in my case it is just saving the hard memory.
|
2

Hi A small correction Your code returns the first digit(not last digit) of the entered number.Here is the reason

You are calculating revNum after returning some value like this

    return(rev(number/10)+revNum);
    revNum=(number%10)*sum; sum=sum/10;

hence the second statement has no effect.

Also revNum is a local variable

So every time when you are calling a recursive function new local copies of sum(local variable) and revNum are getting created and initialized with 0 and 100 respectively.

Your recursive tree looks like this,For example 596 is the number passed to the recursive function.

              rev(596) //call from main
              rev(59)-->rev(5) // these are recursive calles

Now rev(5) returns 5(since 5 < 9) back to the caller i.e to rev(59) from there to the caller which is in main, resulting the display of the first digit, in this case it is 5.

How to fix it?

To fix that issue, you have to make them global variables(sum and revNum) also return statement should be at the end, after calculating the reverse number. Here is the simple code.

I made reverse variable as global to preserve the changes in it, finally I'm returning the same to the caller.

    #include <stdio.h>
    int reverse;           //globally declared
    int rev(int revNum)
    {
       if(revNum)
       {
          reverse = (reverse * 10) + (revNum % 10);
          rev(revNum/10);    //recursive call 
       }
       else              
        return;    //return back to caller when revNum becoms 0
    return reverse;          
    }

   int main()
   {
       int num;
       printf("Enter a number:");
       scanf("%d",&num);
       printf("Reverse Number is:%d\n",rev(num));
       return 0;
   }

3 Comments

This does work, but I am not sure what value reverse holds as its value is not declared; so (reverse*10) would translate into what?
Hi Michael, as it is a global variable, it will get initialized to zero,hence at first time reverse*10 will become zero.
Fails rev(0) as return value not provided.
2

This is a simple beginner question so I think we need to write a simple code to answer it too. In this way we don't need to create new variables.

n%10 gives us the last number,first we print the last one and then we call reverse function gain but now with parameter n/10 so we get rid of last number which is already printed.

Code

int reverse(int n)
{
        if(n<10)
            printf("%d",n);
        else
        {
            printf("%d",n%10); 
            reverse(n/10);
        }
}

2 Comments

Works well for all n >= 0 with incurring int overflow as others.
Suggested simplification: void reverse(int n) { printf("%d",n%10); if (n >= 10) reverse(n/10); } }
1

May be this snippet helps:

//init reversed number with last digit of number
reversed_number=number % 10;
//remove the last digit of number
number=number / 10;

//if number has another digit...
while (number > 0)
{
    //...shift left all digits of the reversed_number by one digit
    //    and add the last digit of number
    reversed_number=reversed_number*10+(number % 10);
    //remove the last digit of number
    number=number / 10;
}

...added later...

The recursive variant looks like this (I used two functions to have the desired signature):

int rev(int number)
{
    return rev_ext(0,number);
}

int rev_ext(int result, int number)
{
    if (number<10)
    {
        return result*10+number;
    }
    else
    {
        result=result*10 + number % 10;
        return rev_ext(result, number / 10);
    }
}

I'm sure it can be written shorter/optimized ;-)

*Jost

1 Comment

@Taylor - yes you are right, but counting the number of digits of the input is somehow "text processing" ;-)
0

Here is the recursive solution:

#include <stdio.h>
#include <string.h>

main()
{
   int pow(int a, int b){
        int p = 1;
        while(b){
            p = p * a;
            b--;
        }
        return p;
    }

    int len(int number) {
        int i = 0;
        while (number) {
            number/=10;
            i++;
        }
        return i;
    }

    int rev(int number) {
        int revNum=0;
        int i = len(number) - 1;

        if(number<=9) {
            return number;
        } else {
            return(number%(10)*pow(10,i) +rev(number/10));
        }
    }
    printf("%d",rev(1234));
}

Comments

0

Check this recursion version.

#include <stdio.h>  
#include<math.h>
int main()                                                  
{
  int n=345;
  printf("%d",rev(n));
}
int len(int number) 
{
  int i;
  for(i=0;number>0;number=number/10,i++);
  return i;
}
int rev(int n)
{
   if (n==0) return 0;
   int val=0;
   val=n%10;
   return (val * pow(10,len(n)-1)+rev(n/10));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.