递归函数打印我认为不应该的东西

时间:2012-10-18 11:44:06

标签: java recursion

我相信我在编程方面有很好的背景,但今天我遇到了一些令我质疑的东西。这是代码:

public class Recursive{
public static void main(String[] args) {
    func(10);        
}

static void func(int x)
{
    if(x > 0) 
    {
        func(x/2);
        System.out.print(x % 2);     // I thought the code won't reach here ever
    }                
}

}

在我看来,这段代码不应该打印任何东西。但它在我编译时实际打印1010。如果System.out.print(x % 2)是在func(X/2)之前编写的,那么它会有意义,但现在看起来不对。对此有何解释?

6 个答案:

答案 0 :(得分:2)

调用func然后打印x%2。

另一方面,如果使用return func(x / 2),则永远不会达到print语句。

答案 1 :(得分:2)

简单。首先,函数func()获取值10。 在内部,它检查是否10> 0.因为它是,它调用func(5 /*10/2 = 5*/)。

然后,因为5> 0,在内部调用func(2)。这是因为.5的截断。 调用func(2/2 /*= 1*/)并执行。 然后,调用返回的func(0)。当它返回时,Print语句以1%2 = 1执行。在内部返回并且再次执行print语句,2%2 = 0.再次返回并再次执行print语句,参数5%2 = 1。返回最后一个print语句再次执行打印0。

答案 2 :(得分:1)

它必须对func进行第二次调用,然后调用已完成,它将在堆栈中完成原始函数。

你需要查找基本的递归理论。

http://en.wikipedia.org/wiki/Recursion_(computer_science)。

如上所述,使用     return func(x / 2) 将从堆栈中删除该函数,因此永远不会到达函数的末尾。

答案 3 :(得分:1)

func(x/2);     ----------------> // Statement # 1
System.out.print(x % 2); ------> // Statement # 2

Statement # 2 如果您返回 Unreachable Block 的值,则 func(x / 2) call Statement # 1

Recursive function calls存储在stack上。因此,对于每次调用,都会生成stack entry,存储当前呼叫,然后转向下一个呼叫。

现在,当达到你的基本条件时,stack开始roll-back,通过弹出函数的先前状态,然后最终到达它开始的位置。

现在,在从堆栈中弹出每个func调用之后,继续执行function中最后一次func()调用(Statement # 2 in this case)的下一个语句,并且完成后,该函数返回,然后在堆栈上调用下一个函数。 (注意: - 如果你有return func(x / 2)代替func(x / 2),那么代码将不会执行下一个语句,而是立即控制堆栈中的下一个函数。因此{{1} }

最后声明

Unreachable Code
System.out.print(x % 2); 完全清空时,

将被执行,并且控件返回

stack

函数调用,位于堆栈的底部。


所以,你的递归是这样的: -

筹码: -

func(x / 2)

假设func(x / 8) --> Base condition func(x / 4) ^ func(x / 2) ^ func(x) --> First invocation 是基本条件。因此,当x / 8完成执行时,执行的下一个语句是: -

func(x / 8) - >此处x的值为 System.out.println(x % 2)

然后从堆栈中弹出此函数,并将控件返回到堆栈中的下一个函数: - original-x / 8,然后执行下一个语句: -

func(x / 4) - >这里System.out.println(x % 2)再次 x

等等。最后,original-x / 4执行 System.out.println(x % 2)

答案 4 :(得分:1)

打印零和零的行为绝对正确。

虽然你的x>严格大于0,但你会用新的x = int(x / 2)进行更深入的递归,因为x是一个整数。

当x <= 1时,你将有x / 2 == 0因此递归停止,你将开始打印x / 2的余数。

在你的情况下:

f(10)->f(5)->f(2)->f(1)->f(0)  
                          |
  0 <-  1  <- 0  <-  1  <-+  

提示:当我遇到这种问题时,我会在代码中放置System.out.println()跟踪以了解流程。如果您使用的是Eclipse / Netbeans / Idea,则可以进入调试模式并单步执行代码。

答案 5 :(得分:0)

嗯乍一看,我认为它不会打印任何东西,但是跟踪代码给了我1010是写答案,因为我们永远不会改变x的值,我的意思是我们正在x上进行操作但是我们正在存储。所以这就是为什么它是1010而不是没有。

好的技巧问题