2010-04-09 96 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 ; 
} 

這裏是這種方法的一個可能的輸出(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 

爲什麼該行的「我藍色「和」我是紅色「印刷?爲什麼他們以相反的順序打印紅色,第一次輸入,最後打印?

+1

見http://stackoverflow.com/questions/2611573#2611589爲什麼遞歸是完全錯誤的這個問題。 – vladr 2010-04-09 23:40:08

回答

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 OU不希望打印的顏色對那些情況下,當用戶回答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 2010-04-09 23:47:02

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()的調用返回後,接下來的其餘部分仍然需要完成。

我喜歡查看它類似於文件目錄樹中的文件夾:試想一下摺疊和展開較低級別的目錄!