Результатом рекурсивной функции является StackOverflowError

1

Я не понимаю, почему эта функция приводит к ошибке. Если бы кто-нибудь мог мне это объяснить, я бы очень признателен!

public static int count7(int n){
    if(n == 0){
        return 0;
    }
    if (n==7){
        return 1;
    }
    if (n%10 == 7){
        return 1 + count7(n/10);
    }
    else{
        return count7(n/10);
    }
}

он отлично работает с "7777777" и тому подобное, но "999999" дает ошибку, а также "123" и "47571".

Поэтому я добавил:

if(n == 0){
        return 0;
    }

и теперь это работает!

  • 0
    Возьмите число 123 и посмотрите, что такое поток выполнения. О, также это довольно плохой пример использования рекурсии (надеюсь, это просто упражнение).
  • 0
    @ZouZou Почему это плохо для рекурсии? И да, это всего лишь упражнение для изучения того, как работает рекурсия и как ее использовать.
Показать ещё 1 комментарий
Теги:
recursion

3 ответа

2
Лучший ответ

В некоторых ситуациях у вас бесконечные рекуррентные вызовы (если n никогда не равно 7).

Например:

n = 123     //initial call
n = 12    //1st recursive call
n = 1    //2nd recursive call
n = 0    //3rd recursive call

Значение никогда не равно n = 7, поэтому вы никогда ничего не возвращаете, и вы продолжаете называть count7 (n/10)

Вы должны изменить свой код, чтобы поймать все базовые случаи:

public static int count7(int n){
if (n==7){
    return 1;
} else if (n < 7) {
    return 0; // I assumed you wanted to return 0, you can change this to return 1...
}
if (n%10 == 7){
    return 1 + count7(n/10);
}
else{
    return count7(n/10);
}
}
  • 0
    Спасибо! Просто добавлю, имеет ли значение, если я делаю только if (n <7), разве мне не нужно добавлять if (n> 7)?
  • 0
    Я бы сделал, если бы (n <= 7) вернул 1, но я не был уверен, хотите ли вы вернуть 1, просто если n == 7. Да, вы можете объединить до двух, если возвращаете одно и то же значение. Обновите свой код выше с тем, что вы думаете, ответ должен быть, и я буду комментировать.
Показать ещё 1 комментарий
0

У вас нет условия остановки. Вы должны добавить туда:

if (n == 0) return 0;
  • 0
    Просто проанализируйте пример 123 в вашем исходном коде. 1-я рекурсия возвращается 0 + count7 (12) 2-я рекурион возвращается 0 + count7 (1) 3-я рекурион и бесконечность возвращаются 0 + count (0)
  • 0
    А-а-а-а-а-а-ах, целочисленное деление.
0

Ну, когда два условия не выполняются конкретно на последней цифре, он просто вызывает блок else

return count7(n/10)

с 0 из-за деления целочисленного целого числа на 10, он обрезается до 0 и, таким образом, не соответствует условиям, вызывающим эту строку, до тех пор, пока не произойдет переполнение. Вы можете добавить базовый оператор с указанием

if(n==0) return 0;

Кроме того, чтобы помочь в процессе отладки, я предлагаю вам отслеживать процесс с помощью операторов печати, чтобы узнать, что происходит с вашими переменными. Например, добавьте

System.out.println("n = " + n);

перед каждым из операторов возврата.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню