C: Рекурсивная функция для инвертирования int

У меня вчера была эта проблема на экзамене. Я не мог решить это, так что вы можете представить результат ...

Создайте рекурсивную функцию: int invertint (int num), которая получит целое число и вернет его, но в инвертированном виде, например: 321 вернется как 123.

Я написал это:

int invertint( int num ) {
  int rest = num % 10;
  int div = num / 10;
  if( div == 0 ) {
     return( rest );
  }
  return( rest * 10 + invert( div ) )
}

Работает для 2-значных номеров, но не для 3-х и более цифр. Поскольку 321 вернет 1 * 10 + 23 на последнем этапе.

Большое спасибо!

PS: Есть ли способ быстрее разобраться в подобных проблемах рекурсии или все зависит от воображения?


person JorgeeFG    schedule 05.07.2012    source источник
comment
Рассматривали ли вы преобразование его в char * и вызов рекурсивной функции с помощью char *? Наверное, это упрощает жизнь, но я не знаю, разрешили ли вам это делать   -  person Dan    schedule 05.07.2012
comment
Каким будет результат 1230, 3210 или 321?   -  person Jo So    schedule 05.07.2012
comment
@JoSo Я думаю, что в целом числе не может быть ведущего 0 ... так что я думаю, это будет: 1230: 321   -  person JorgeeFG    schedule 05.07.2012
comment
Если вы ищете подсказки о том, как решить эту проблему, я предлагаю: 1) Постарайтесь придерживаться структуры if(is_base_case){ basecase } else { recursive_case }. Это становится естественным с практикой и 2) Узнайте, как преобразовать хвостовую рекурсию в циклы while и наоборот. Под эту категорию попадают многие виды проблем.   -  person hugomg    schedule 05.07.2012


Ответы (7)


Ваша ошибка в том, что в последнем утверждении вы умножаете rest на 10. Почему только 10? Вам нужно сдвинуть цифру rest на столько цифр, сколько осталось в оставшейся части числа. Вы переключаетесь только на 1. Неудивительно, что это работает только для 2-значных чисел.

Последнюю часть нужно выполнить по линиям

int tail = invert( div );
int deg = /* number of digits in `tail` */;
return rest * (int) pow(10, deg) + div;
person AnT    schedule 05.07.2012
comment
+1. Это был ответ, о котором я тоже подумал. Но не должно быть (количество цифр в хвосте - 1). Например: 321 состоит из 3 цифр, поэтому при последнем выполнении должно быть rest * pow (10, 2). - person Jay; 05.07.2012
comment
@Jay: tail в данном случае - это фактически оставшаяся часть числа (которая уже была передана через рекурсивный вызов). Т.е. если исходный номер был 321, то rest - это 1, а tail - это 23. Итак, deg будет 2, как и должно быть. Однако я уже вижу проблему с этим решением, если tail заканчивается ведущими нулями после инверсии. Количество цифр должно быть вычислено до рекурсивного вызова. BLUEPIXY делает это правильно в принятом решении. - person AnT; 05.07.2012

Проблема с return(rest * 10 + invert(div)). Самостоятельно произвести умножение не получится. Коэффициент зависит от того, сколько раз функция рекурсивно повторяется, поэтому вы должны предоставить перенос в качестве второго аргумента вашей функции (перенос инициализируется 0)

person Jo So    schedule 05.07.2012

Если вы сделаете это по-другому, счетчик вам не понадобится.

int invertint(int num)
{
    if (0 == num || 0 == num % 10) {
        return num / 10;
    }
    int digits = floor(log10(num)) + 1;
    int modulus = pow(10, digits - 1);
    return invertint(num % modulus) * 10 + num / modulus;
}

Обратите внимание, что это не так просто, как я думал изначально - мне пришлось использовать математику.

person cha0site    schedule 05.07.2012
comment
Это то же самое, что и ответ Рафаэля Баптисты, и это так же неверно. - person interjay; 05.07.2012
comment
@interjay: Вообще-то ты прав. Дай мне еще подумать об этом. - person cha0site; 05.07.2012
comment
Да, теперь должно работать, +1. Я не думаю, что вопрос экзамена очень хорош, потому что он требует, чтобы вы либо использовали плавающую точку для подсчета цифр, либо использовали цикл (что глупо, когда речь идет об использовании рекурсии). - person interjay; 05.07.2012
comment
@interjay: Согласен. К сожалению, я думаю, что это довольно распространенное явление, по какой-то причине большинство дидактических примеров рекурсии не очень хорошо используют рекурсию. - person cha0site; 05.07.2012

int reverse(int no,int rev)
{
if(no!=0)
return reverse(no/10,rev*10+no%10);
else
return rev;
}

вызовите этот метод как reverse (numberToReverse, 0)

person Kalai Selvan Ravi    schedule 05.07.2012
comment
Ваша вторая функция на самом деле не работает, вы даже не используете результат рекурсивного вызова. - person interjay; 05.07.2012
comment
Нет, не пойдет. Вы даже не возвращаете значение из функции. -1 за споры, когда вы явно не тестировали. - person interjay; 05.07.2012
comment
@interjay Я удалил эту функцию. После того, как протестирую, выложу. - person Kalai Selvan Ravi; 05.07.2012
comment
ОК, -1 удалено. Я не думаю, что есть простой способ ответить на вопрос без добавления дополнительного параметра или подсчета количества цифр. - person interjay; 05.07.2012

В качестве альтернативы это можно было бы сделать без рекурсии.

    int invertint(int num)
    {
        int res = 0;
        while (num != 0)
        {                
            res = res * 10 + (num % 10);
            num /= 10;
        }
        return res;
    }

Но поскольку рекурсия была назначением, учитывая подпись int (int), проще всего было бы использовать вариант pow (log10)) (при условии, что вам разрешено включать math.h?)

    int invertint(int num)
    {
        if (num == 0) return 0;
        return invertint(num / 10)  +  (int)pow(10, (int)log10(num)) * (num % 10);
    }
person Me.Name    schedule 05.07.2012

Это самый простой подход.

int sum=0;
int reverse(int n)
{
    if(n>0)
    {
        sum=(sum*10)+(n%10);
        reverse(n/10);
    }
    return sum;
}
person Jishnu Dev Roy    schedule 09.06.2017
comment
Почему вы используете глобальную переменную? - person All Workers Are Essential; 09.06.2017

person    schedule
comment
Отлично работает, спасибо. Если это не беспокоит, не могли бы вы объяснить, как вы это подумали? Спасибо! - person JorgeeFG; 05.07.2012
comment
@Jorge: Идея состоит в том, чтобы рекурсировать наоборот - вместо того, чтобы обрабатывать сначала крайнюю правую цифру, вы обрабатываете крайнюю левую. Вот что делает здесь цикл и комбинация _1 _ / _ 2_ в моем ответе. Остальное дается довольно естественно. - person cha0site; 05.07.2012
comment
@Jorge - i: 10 ^ floor (log10 (num)), объяснил cha0site. - person BLUEPIXY; 05.07.2012