从计算杨辉三角(Pascal Triangle)看算法优化

来源:互联网 发布:剑三霸刀成女脸型数据 编辑:程序博客网 时间:2024/05/16 17:48

杨辉,字谦光,北宋时期杭州人。在他1261年所著的《详解九章算法》一书中,辑录了三角形数表,称之为“开方作法本源”图。 杨辉三角是一个由数字排列成的三角形数表,一般形式如下:          

      1
         1 1
        1 2 1
       1 3 3 1
      1 4 6 4 1
     1 5 10 10 5 1

杨辉三角最本质的特征是,它的两条斜边都是由数字1组成的,而其余的数则是等于它肩上的两个数之和。根据这一特征,我们可以用程序方便地实现输出杨辉三角。实现算法有很多,下面给出其中两种。

1、递归算法: F(i, j) = F(i-1, j-1) + F(i-1, j)

#include <stdio.h>

#include <stdlib.h>

long long pascal_triangle(int row, int col)
{
    if (col == 1 || row == col)
        return 1;
    return pascal_triangle(row-1, col-1) + pascal_triangle(row-1, col);
}

int main(int argc, char *argv[])
{
    int i, j;
    int row = atoi(argv[1]);
   
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= i; j++)
            printf("%u ", pascal_triangle_inc(i, j));
        printf("/n");
    }

    return 0;
}

 

2、增量算法,使用一组数据保存已计算的值,占用O(n)额外存储空间

#include <stdio.h>

#include <stdlib.h>

long long pascal_triangle_inc(int row, int col, long long *a)
{
    if (col == 1 || row == col)
    {
        a[row*(row-1)/2 + col - 1] = 1;
        return 1;
    }
    //a[row-1][col-1] = a[row-2][col-2] + a[row-2][col-1];
    a[row*(row-1)/2 + col - 1] = a[(row-1)*(row-2)/2 + col - 2] + a[(row-1)*(row-2)/2 + col - 1];
    return a[row*(row-1)/2 + col - 1];
}

int main(int argc, char *argv[])
{
    int i, j;
    int row = atoi(argv[1]);
    long long *a = (long long *)malloc((row*(row+1))/2 * sizeof(long long));
    if (a == NULL)
    {
        perror("malloc");
        return -1;
    }

    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= i; j++)
            printf("%u ", pascal_triangle_inc(i, j, a));
        printf("/n");
    }

    free(a);
    return 0;
}

上面两种算法,递归算法简洁,但性能很大,存在太多的重复计算,当杨辉三角大时,计算非常慢。而增量算法,使用数组对先前计算结果进行保存,用于计算后续的数值,有效消除了冗余计算,以空间复杂性换取了计算复杂性,性能得到了很大的提升。在我自己的机器进行测试,递归算法计算row = 30时就比较困难了,而增量算法可以很快输出row = 1000的杨辉三角。当 row = 30时,两种算法的消耗时间分别如下:

time ./triangle 30

real    0m36.314s

user   0m21.201s

sys     0m0.004s

 

time ./triangle_inc 30

real    0m0.002s

user   0m0.000s

sys     0m0.000s

可见,增量算法在时间复杂性方面要远远优于递归算法,只是增加了一定的空间复杂性。所以,鱼和熊掌常常不可得兼。

其实,我先写了递归算法,发现其性能不可接受,于是给出了增量算法。数据结构和算法,是软件开发人员的基本功。当需要对程序性能进行调优时,就可以发现其巨大的威力。

 

(Aiguille LIU / 刘爱贵 / aigui.liu@gmail.com)

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 指甲上有荧光剂怎么办 小孩吃了荧光剂怎么办 毛巾上有荧光剂怎么办 用过劣质面膜后怎么办 液体硅胶奶嘴煮完有味怎么办 后跟贴粘在鞋上怎么办 优化营商环境公安怎么办 提升营商环境公安怎么办 准予迁入证明过期了怎么办 粉底液容易脱妆怎么办 家人进了火疗传销怎么办 自发热护膝洗了怎么办 用气垫bb卡粉怎么办 贴药膏后皮肤过敏红肿怎么办 贴完膏药皮肤痒怎么办 猕猴桃吃的嘴疼怎么办 摩拜单车怎么办月卡 出国忘了带护照怎么办 雅漾喷雾失压了怎么办 洗衣服时衣服粘上卫生纸怎么办 一晚上卫生巾都是满的怎么办 宝宝头上痱子痒怎么办 短裤里的宽松紧带拧了怎么办 肉色内衣被染黑色了怎么办 安全裤总往上缩怎么办 夏天穿裙子膝盖怕凉怎么办 夏天穿裙子膝盖冷怎么办 天凉嗓子痒咳嗽怎么办 棉服里面跑毛怎么办 棉衣里面的棉一块一块的怎么办 穿姨妈巾悟出痱子怎么办 穿裙子上衣太长了怎么办 微信封号了零钱怎么办 快递加盟商欠我工资怎么办 加盟费交了以后怎么办 加盟总部违约加盟商该怎么办 自行车锁钥匙丢了怎么办 假体隆胸肿胀痛怎么办 恶露60天不干净怎么办 剖腹产俩月恶露不干净怎么办 剖腹产恶露一个多月还没干净怎么办