2014-11-30 3 views
1

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

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 Почему это плохое использование для рекурсии? И да, это всего лишь упражнение для изучения того, как работает рекурсия, и она использовалась. – Gurkang

+0

Потому что это те методы, которые вы могли бы сделать, используя простой цикл. –

ответ

2

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

Например:

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

значение никогда не является п = 7, поэтому вы никогда не вернуть ничего, и вы продолжать называть count7 (п/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)? – Gurkang

+0

Я бы сделал if (n <= 7) return 1, но я не был уверен, что вы хотите вернуть 1, только если n == 7. Да, вы можете объединить два, если вы возвращаете одно и то же значение. Обновите свой код выше тем, что, по вашему мнению, должен быть, и я буду комментировать. –

+1

Первый оператор if возвращает if (n == 7), второй возвращает if (n <7). Добавление if (n> 7) является излишним, потому что в этой точке оно всегда будет истинным (логически невозможно достичь этого кода, если n> 7 истинно). –

0

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

if (n == 0) return 0; 
+0

Просто проанализируйте пример 123 в вашем исходном коде. 1-я рекурсия возвращается 0 + count7 (12) 2-й возврат возвращается 0 + count7 (1) 3-й возврат и бесконечность, возвращающий 0 + счет (0) –

+0

Ahh good ole integer division. –

0

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

return count7(n/10) 

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

if(n==0) return 0; 

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

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

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

Смежные вопросы