快速确定递归函数返回的最终值

时间:2015-11-19 12:20:53

标签: c recursion

昨天我参加的考试中提到的一个问题让我很着迷。

G:
 CMP R0,#100   [Register R0 has the argument. Also the return value.]
 BLT Label     [Branch if less than]
 SUB R0,#10
 RET

Label:
 ST R14, [SP]  [Store the return address of the caller on stack]
 SUB SP,#4     [Update the stack pointer]
 ADD R0,#11
 BL G          [G(n+11)] Uses value in R0 as argument, Returns value in R0 
 BL G          [G(G(n+11))] same comments as above 
 ADD SP,#4
 LD R14,[SP]
 RET 

我们被要求从四个选择中选择G(10)的正确结果。我回到家里,在我的电脑上写下程序,然后把91作为答案。事实上,91被列为答案之一。

决心达到相同的答案,我手动编写了一个相当于得到答案的汇编程序[思考在它们全部展开之前最多会产生10-12个堆栈帧]。

Type[] coltypes = {string, string, string, string, string, string };

然后我为每次调用手动重新创建堆栈帧,并且帧不断增加。在大约20个堆叠帧,我放弃了。

我的装配程序可疑,我继续在C程序中插入一个计数器,它表示该功能已输入183次。

显然,这是一个需要在5分钟内解决的问题,因此必须有一个更简单的解决方案,如拇指规则或图表等。

你怎么能在不到5分钟内得到答案?

2 个答案:

答案 0 :(得分:4)

如果n>那么G(n)是什么? 100?

如果n = 100,G(n)是多少?

如果n = 99,G(n)是多少? (使用上面的答案)。

如果n = 98,G(n)是多少? (使用上面的答案)。

...

如果n = 90,G(n)是多少? (使用上面的答案)。

如果n = 89,那么G(n)是多少? (使用n = 100和n = 91的答案)。

等等。会有一个非常非常明显的模式。

答案 1 :(得分:0)

Note that an optimizing compiler will rearrange the code a bit and generate a tail recursive loop:

G       proc
        mov     eax, DWORD PTR [esp+4]   ;n
        add     eax, 11
        cmp     eax, 100
        jle     SHORT G0
        add     eax, -10
        jmp     SHORT G1

G0:     push    eax
        call    G
        add     esp, 4
G1:     cmp     eax, 100
        jle     SHORT G2
        add     eax, -10
        ret     0

G2:     mov     DWORD PTR [esp+4], eax  ;n
        jmp     G                       ;tail recursion
G       endp