Reputation: 131
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!!!
Upvotes: 2
Views: 23360
Reputation: 448
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);
}
}
Upvotes: 2
Reputation: 591
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);
}
Upvotes: 9
Reputation: 4357
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.
Upvotes: 12
Reputation: 1169
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;
}
Upvotes: 2
Reputation: 1263
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));
}
Upvotes: 0
Reputation: 2992
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.
Upvotes: 7
Reputation: 2232
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));
}
Upvotes: 0
Reputation: 1569
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
Upvotes: 1