Что не так с этим методом? - PullRequest
3 голосов
/ 10 апреля 2010

Вот метод:

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 ; 
}

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

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

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

Ответы [ 4 ]

5 голосов
/ 10 апреля 2010

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

    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 (вы не хотите печатать цвет для этих случаев, когда пользователь ответил No, случаи, к которым вы обращаетесь в обратном порядке, когда вы раскручиваете свою рекурсию - причина обратного порядка, в котором были напечатаны другие ответы.)

Также обратите внимание, что вам не нужна (и не нужна) рекурсия в этом конкретном примере: после добавления else ваш метод становится хвост-рекурсивным , и вы можете достичь тот же эффект итеративно . Устраняя рекурсию, вы также устраняете проблему с уязвимостью, то есть возможность того, что злонамеренный пользователь введет 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 ; 
    }
  }
}
3 голосов
/ 10 апреля 2010

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

if (a.equals ("n") || a.equals("N"))
{
  return CPUcolor();
}
2 голосов
/ 10 апреля 2010

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

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 () все остальное еще предстоит сделать.

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

0 голосов
/ 10 апреля 2010

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

...