这个方法有什么问题?

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
请参考https://dev59.com/L03Sa4cB1Zd3GeqPsRcI,了解为什么递归对于这个问题来说是完全错误的。 - vladr
4个回答

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

这样,您只需在用户实际回答“是”时打印颜色(您不希望为用户回答“否”的那些情况打印颜色,在这些情况下,您将按相反的顺序解开递归并重新访问,这就是其他答案打印的反向顺序的原因)。
此外,请注意在这个特定的例子中您不需要(也不希望)递归:一旦您添加了else,您的方法就变成了尾递归,您可以通过迭代实现相同的效果。通过消除递归,您还可以消除一个漏洞问题,即恶意用户可能会输入No无限次,直到您的程序最终由于StackOverflow异常崩溃
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
那很简单 递归。你在 CPUcolor() 中又调用了 CPUcolor()。当调用返回时,每个原始方法的剩余命令将被执行。
要修复它,你需要添加一个返回语句:
if (a.equals ("n") || a.equals("N"))
{
  return 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()调用返回后,其后面的操作仍需完成。

我喜欢将其类比于文件目录树中的文件夹:想象一下展开和折叠较低级别的目录!


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接