简体   繁体   中英

Reverse Numbers function using recursion in C

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!!!

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.

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

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 is a local variable 也是一个局部变量

So every time when you are calling a recursive function new local copies of (local variable) and revNum are getting created and initialized with 0 and 100 respectively. (局部变量)和 revNum 的新本地副本,并分别使用 0 和 100 进行初始化。

Your recursive tree looks like this,For example 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 ie 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.

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

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

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

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

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

Here is mine

int reverseTheNumber(int number, int reverseNumber) {

if (number != 0) {
    reverseNumber += number % 10;
    reverseNumber *= 10;
    return reverseTheNumber(number / 10, reverseNumber);
}
else {
    return reverseNumber / 10;
}

}

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