2010-04-09 4 views
3

Вот метод:Что не так с этим методом?

public static String CPUcolor() 
{ 
    System.out.println ("What color am I?") ; 
    String s = getIns() ; 
    System.out.println ("are you sure I'm "+s+"? (Y/N)") ; 
    String a = getIns() ; 
    while (!((a.equals ("y")) || (a.equals ("Y")) || (a.equals ("n")) || (a.equals ("N")))) 
     { 
      System.out.println ("try again") ; 
      a = getIns() ; 
     } 
    if (a.equals ("n") || a.equals("N")) 
     {CPUcolor() ;} 
    System.out.println ("I am "+s) ; 
    return s ; 
} 

здесь возможный выход этого метода (у-х и п являются пользовательские вводы):

What color am I? 
red 
are you sure I'm red? (Y/N) 
N 
What color am I? 
blue 
are you sure I'm blue? (Y/N) 
N 
What color am I? 
Yellow 
are you sure I'm Yellow? (Y/N) 
y 
I am Yellow 
I am blue 
I am red 

Почему это, что линия в «Я синий "и" Я красный "? Почему они печатаются в обратном порядке с красным, первое введенное, напечатанное последним?

+1

См. Http://stackoverflow.com/questions/2611573#2611589, почему рекурсия является неправильной для этой проблемы. – vladr

ответ

3

Это просто recursion. Вы снова вызываете CPUcolor() в свой CPUcolor(). Когда вызов вернется, остальные команды каждого оригинального метода будут выполнены.
Чтобы исправить это, вы должны добавить возврата:

if (a.equals ("n") || a.equals("N")) 
{ 
    return CPUcolor(); 
} 
5

Обратите внимание, что

if (a.equals ("n") || a.equals("N")) 
     {CPUcolor() ;} 
    System.out.println ("I am "+s) ; 

должно быть:

if (a.equals ("n") || a.equals("N")) 
     {CPUcolor() ;} 
    else 
     {System.out.println ("I am "+s) ;} 

Таким образом, вы печатать только цвет в одиночке пример , когда пользователь фактически ответил Yes (y НУ не хотят печатать цвет для тех случаев, когда пользователь ответил No, экземпляры, которые вы в обратном пересмотреть существующие для того, как вы unwind your recursion - причина обратной последовательности, в которой были напечатаны другие ответы)

. Также обратите внимание, что вам не нужно (и не хотите) рекурсии в этом конкретном примере: после добавления else ваш метод становится tail-recursive, и вы можете добиться такого же эффекта iteratively. Исключив рекурсии вы также устранить проблему уязвимости, то есть возможность злоумышленником не входя No на неопределенный срок до вашей программы в конечном счете аварии с StackOverflowException:

public static String CPUcolor() 
{ 
    while (true) { 
    System.out.println ("What color am I?") ; 
    String s = getIns() ; 
    System.out.println ("are you sure I'm "+s+"? (Y/N)") ; 
    String a = getIns() ; 
    while (!((a.equals ("y")) || (a.equals ("Y")) || (a.equals ("n")) || (a.equals ("N")))) 
     { 
      System.out.println ("try again") ; 
      a = getIns() ; 
     } 
    if (a.equals ("y") || a.equals("Y")) { 
     System.out.println ("I am "+s) ; 
     return s ; 
    } 
    } 
} 
+1

+1 для «вам не нужна рекурсия». – BalusC

0

Потому что вы звоните новый CPUColor (), прежде чем распечатать результаты этого.

2

Я отступом вывод, чтобы сделать его немного яснее, что происходит:

What color am I? 
red 
are you sure I'm red? (Y/N) 
N 
    What color am I? 
    blue 
    are you sure I'm blue? (Y/N) 
    N 
     What color am I? 
     Yellow 
     are you sure I'm Yellow? (Y/N) 
     y 
     I am Yellow 
    I am blue 
I am red 

Каждый уровень отступов один уровень глубже в иерархии вызовов: еще один вызов CPUColor(). После того, как вызов CPUColor() возвращается, остальное, что следует, должно быть выполнено.

Мне нравится просматривать его аналогично папкам в дереве каталогов файлов: Представьте, что вы складываете и расширяете нижние уровни каталогов!

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

  • Нет связанных вопросов^_^