zoukankan      html  css  js  c++  java
  • 为什么我的递归调用次数和书上的不一样?

    为什么我的递归次数和书上的不一样

    根据《算法导论》中钢条切割问题的描述

    我按照他的描述,计算了一遍函数调用次数

    按理说:

    cut_rod(int * p , int n)

    当 n = 0 时,cut_rod(p,0) 会直接返回,调用次数为 1。

    当 n = 1 时,会调用一次 cut_rod(p, 1),在 cut_rod(p, 1) 内部,还有一次 cut_rod(p, 0),一共调用2 次。

    由数学归纳法,可以推导出,调用次数 $$ T(n) = 2^n $$

    然而,我运行的结果却是:

    image-20211016210420237

    下面是我的代码,你能看出是哪里出了问题吗?

    #include <stdio.h>
    #include <limits.h>
    
    #define N 10
    #define max(x, y) ((x)>(y) ? (x) : (y))
    
    unsigned int times = 0;
    int cut_rod(int * p, int n);
    
    void main(void)
    {
        int p[N+1] = {0,1,5,8,9,10,17,17,20,24,30};
        int i;
        for (i = 0; i <= N; i++)
        {
            times = 0;
            printf("The optimal profit of %d is %3d
    ", i, cut_rod(p, i));
            printf("function call times: %4d 
    ", times);
        }
    }
    
    int cut_rod(int * p, int n)
    {
        int r;
        int i;
        times++;
        if (n == 0)
            return 0;
        r = INT_MIN;
        
        for (i = 1; i <= n; i++)
        {
            r = max(r, p[i] + cut_rod(p, n-i));    
        }
        return r;
        
    }
    
    

    我用了 gdb 看,愣是没看出问题在哪。

    为什么我的递归次数和书上的不一样

    幸好,我还有一个好兄弟,他火眼金睛,一下子就找到问题所在:

    问题出现在这里

    r = max(r, p[i] + cut_rod(p, n-i));

    我调用了一个宏定义函数 max

    #define max(x, y) ((x)>(y) ? (x) : (y))

    宏定义其实是在预编译阶段将程序中出现的宏替换成宏后面的字符串

    max(r, p[i] + cut_rod(p, n-i))

    将按照下面的步骤被替换

    x 被换成 r, y 被换成 p[i] + cut_rod(p, n-i)

    如下图:

    image-20211016220309306

    于是,替换后的程序就变成了

     for (i = 1; i <= n; i++)
     {
         r = (r) > (p[i] + cut_rod(p, n-i)) ? (r) : (p[i] + cut_rod(p, n-i));    
     }
    

    这样,我能明显的看出

    r <= p[i] + cut_rod(p, n-i) 时,cut_rod(p, n-i) 被执行了2次

    这样就能解释,GDB调试时,当n = 1时进行到递归调用时,为什么会出现第2次cut_rod()调用了。

  • 相关阅读:
    2018/01/01Java基础学习——如何通过dos系统的javadoc命令生成API文档
    Go语言的big包实现大整数运算
    HDU5100 Chessboard【组合数学】
    HDU5143 NPY and arithmetic progression【暴力】
    UVALive5402 UVA579 Clock Hands【水题】
    UVA11799 Horror Dash【求极值+水题】
    HDU1017 ZOJ1152 A Mathematical Curiosity【暴力】
    UVALive2536 POJ1248 HDU1015 ZOJ1403 Safecracker【密码+暴力】
    POJ1284 Primitive Roots【原根】
    UVA11340 Newspaper【输入流+map】
  • 原文地址:https://www.cnblogs.com/studentWangqy/p/15415640.html
Copyright © 2011-2022 走看看