Cbeginner
Cbeginner

Reputation: 59

A recursive function that determines whether the digits of a number are in ascending order

I'm practicing recursion and my solution to the problem doesn't seem to work. I'm trying to write a recursive code that will determine if the digits of a number are in ascending order or not. here's my code:

#include <stdio.h>
int isAscending(int num);
int main(){
    int result;
    result = isAscending(123);//Should print "The number is in ascending order!"
    if (result == 0) {
        printf("The number is in ascending order!\n");
    }
    else {
        printf("The number is not in ascending order!\n");
    }
}
int isAscending(int num) {
    int new = num / 10;
    int result = 0;
    if ((num % 10) == 0) {
        return 0;
    }
    else if ((num % 10) > (new % 10)) {
        result += isAscending(num / 10);
        return result;
    }
    else {
        return 1;
    }
}

Upvotes: 1

Views: 2950

Answers (6)

chqrlie
chqrlie

Reputation: 144695

Your tests are incorrect. You should return true for numbers with a single digit, false if the last digit is less or equal to the previous one and recurse for the rest:

int isAscending(int num) {
    int new = num / 10;

    if (new == 0) {
        return 1;
    } else
    if (num % 10 <= new % 10) {
        return 0;
    } else {
        return isAscending(new);
    }
}

This kind of recursion is called tail recursion as you return the result of the recursive call. Good compilers will generate iterative code equivalent to this:

int isAscending(int num) {
    for (;;) {
        int new = num / 10;

        if (new == 0) {
            return 1;
        }
        if (num % 10 <= new % 10) {
            return 0;
        }
        num = new;
    }
}

Upvotes: 0

cdlane
cdlane

Reputation: 41872

This solution returns 0 on failure otherwise some other integer on success. It seems that isDescending() is easier to write when returning 0 as a failure value but I contorted this accordingly:

#include <stdio.h>
#include <stdlib.h>

int isAscending(int num) {
    int quotient = num / 10;
    int remainder = num % 10;

    if (quotient != 0) {

        int result = isAscending(quotient);

        if (result == 0 || result >= remainder) {
            return 0;
        }
    }

    return remainder;
}

int main(int argc, char **argv) {
    if (isAscending(atoi(argv[1]))) {
        printf("The number is in ascending order!\n");
    } else {
        printf("The number is not in ascending order!\n");
    }

    return 0;
}

TESTS

% ./a.out 123
The number is in ascending order!
% ./a.out 321
The number is not in ascending order!
% ./a.out 101
The number is not in ascending order!
% 

No, it doesn't handle negative numbers! It also doesn't handle '0' correctly as an input -- other single digit numbers are fine.

Again, isDescending() is easier to write but unfortunately, !isDescending() != isAscending()

Upvotes: 0

babon
babon

Reputation: 3774

Here's another (bare-bones) way to go about it. The basic idea is that if we have a single digit, we return affirmative, else we check if the rightmost number is greater than the one just to it's left. And we do this for the remaining digits.

#include <stdio.h>

int isAsc(int i)
{
    int rem = i % 10;    // remainder
    int quo = i / 10;    // quotient

    if (rem == i)
        return 1;
    else if (rem <= (quo % 10))
        return 0;
    else
        return 1 && isAsc(quo);
}

int main(void)
{
    int i = 123123;
    if (isAsc(i))
        printf("%s\n", "Ascending");
    else
        printf("%s\n", "Not ascending");

    return 0;
}

Upvotes: 2

Cbeginner
Cbeginner

Reputation: 59

I fixed my code and it works, thanks for the help!:

#include <stdio.h>
int isAscending(int num);
int main(){
    int result;
    result = isAscending(2589);//Should print "The number is in ascending order!"
    if (result == 0) {
        printf("The number is in ascending order!\n");
    }
    else {
        printf("The number is not in ascending order!\n");
    }
}
int isAscending(int num) {
    int new = num / 10;
    int result = 0;
    if ((num % 10) == 0) {
        return 0;
    }
    else if ((num % 10) > (new % 10)) {
        return isAscending(num / 10);
    }
    else {
       return 1 + isAscending(num / 10);
    }
}

Upvotes: -1

Emanuele Giona
Emanuele Giona

Reputation: 781

It would be better to use another parameter to store the last digit, which is going to be "dropped" in the current iteration.

So I came up with the following recursive logic:

  • use a parameter which stores the last digit dropped

  • base case: if the number is 0, return 0 (true)

  • calculate the current last digit of the number (number%10)

  • if the current last digit is greater than the last digit dropped: is this case, return 1 (false)

  • if not, return isAscendingRecursive() on the new number dropping the current last digit and pass it as the next iteration last digit.

Code:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** args){
    int num=0;
    printf("Insert a number:\n");
    scanf("%d",&num);
    if(isAscending(num)==0)
        printf("Ascending\n");
    else
        printf("Not ascending\n");
}

int isAscending(int num){
    return isAscendingRecursive(num,9);
}

int isAscendingRecursive(int num, int lastDigit){
    if(num == 0)
        return 0;

    int temp = num%10;
    if(temp > lastDigit)
        return 1;
    else
        return isAscendingRecursive(num/10, temp);
}

Upvotes: 0

praveen
praveen

Reputation: 291

Can you please try below recurrsive code:

`

boolean isascending(int num){

if(num == 0) return true;
if(num%10>num%100) return isascending(num/10);
else return false;
}`

or you can use while loop:

while(num>0){
if(num%10 > num%100){
   num = num/10;
   continue;
} return false;
} return true;

Upvotes: 0

Related Questions