这种方法有什么问题?

时间:2010-04-09 23:23:53

标签: java recursion tail-recursion

以下是方法:

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 个答案:

答案 0 :(得分: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 时,您仅在单个实例中打印颜色(您不想为这些实例打印颜色)当用户回答No时,您unwind your recursion 的相反顺序重新访问的实例 - 打印其他答案的相反顺序的原因。)

另请注意,在此特定示例中您不需要(也不想要)递归:添加else后,您的方法变为tail-recursive,您就可以实现同样的效果iteratively。通过消除递归,您还可以消除漏洞问题,即恶意用户可能无限期地输入No,直到您的程序最终StackOverflow Exception 崩溃为止:

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 :(得分:3)

这很简单recursion。您再次在CPUcolor()内拨打CPUcolor()。当调用返回时,将执行每个原始方法的剩余命令 要修复它,你必须添加一个返回:

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

答案 2 :(得分: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()返回后,仍然需要完成后面的其余部分。

我喜欢与文件目录树中的文件夹类似地查看它:想象一下折叠和扩展较低级别的目录!

答案 3 :(得分:0)

因为你在打印出这个结果之前调用了新的CPUColor()。