C语言·实现杨辉三角的打印

PS:这篇笔记的代码编写环境是macOS系统自带的Xcode.

1. 最朴素的解法

二维数组,先填充,后打印的方法,是最容易想到的。
即,将所有位置先置为零,后填充最有特点的1,然后,逐个逐行计算出别的,进行填充。

#import <stdio.h>
#define line 10

int main(int argc, const char * argv[]) {
    //printf("%lu", sizeof(int));
    // 初始化 变量
    int i, j, n = line;
    // 初始化 数组
    int array[line][line] = { 0 };
    
    // 每行的第一个元素、最后一个元素 均为 1
    for (i = 0; i < n; i++) {
        array[i][0] = 1;
        array[i][i] = 1;
    }
    // 每行左右两边都是 1
    // 从第二行起,中间的每一个数是上一行里相邻两个数之和
    // 第 n 行 有 n 个数字
    // 因为第1行 第2行 均为已知
    // 所以 从第三行开始
    // 从第三行开始计算(i = 2)
    // 每一个空格的内容都是它左上方和上方两个元素之和
    for (i = 0; i < n; i++) {
        for (j = 1; j <= i; j++) {
            // 计算 填充数组
            array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
        }
    }
    
    // 打印二维数组
    int k;
    for (i = 0; i < n; i++) {
        // 打印每行前面的空格
        for (k = i; k < n - 1; k++) {
            printf("   ");
        }
        // 打印每行的每个元素的具体值
        for (j = 0; j <= i; j++)
            printf("%6d", array[i][j]);
        // 每行打印完 进行换行
        printf("\n");
    }
    return 0;
}
2. 优化一点的做法

就是,可以减少一个循环的做法。

#import <stdio.h>
#define line 10

int main(int argc, const char * argv[]) {
    //printf("%lu", sizeof(int));
    // 初始化 变量
    int i, j, n = line;
    // 初始化 数组
    int array[line][line] = { 0 };
    // 每行左右两边都是 1
    // 从第二行起,中间的每一个数是上一行里相邻两个数之和
    // 第 n 行 有 n 个数字
    // 因为第1行 第2行 均为已知
    // 所以 从第三行开始
    // 从第三行开始计算(i = 2)
    // 每一个空格的内容都是它左上方和上方两个元素之和
    for (i = 0; i < n; i++) {
        // 将上面的循环放入这里,减少一个循环
        array[i][0] = 1;
        for (j = 1; j <= i; j++) {
            // 计算 填充数组
            array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
        }
    }
    
    // 打印二维数组
    int k;
    for (i = 0; i < n; i++) {
        // 打印每行前面的空格
        for (k = i; k < n - 1; k++) {
            printf("   ");
        }
        // 打印每行的每个元素的具体值
        for (j = 0; j <= i; j++)
            printf("%6d", array[i][j]);
        // 每行打印完 进行换行
        printf("\n");
    }
    return 0;
}
3. 继续优化的做法

方法1. 和方法2. 都是用的遍历,一遍填充,一遍打印。
此处尝试将填充和打印放在一起做。

#import <stdio.h>
#define line 10

int main(int argc, const char * argv[]) {
    //printf("%lu", sizeof(int));
    // 初始化 变量
    int i, j, n = line;
    // 初始化 数组
    int array[line][line] = { 0 };
    
    // 每行左右两边都是 1
    // 从第二行起,中间的每一个数是上一行里相邻两个数之和
    // 第 n 行 有 n 个数字
    // 因为第1行 第2行 均为已知
    // 所以 从第三行开始
    // 从第三行开始计算(i = 2)
    // 每一个空格的内容都是它左上方和上方两个元素之和
    int k;
    for (i = 0; i < n; i++) {
        // 打印每行前面的空格
        for (k = i; k < n - 1; k++) {
            printf("   ");
        }
        // 每行第一个元素
        array[i][0] = 1;
        // 打印每行第一个元素
        printf("%5d", 1);
        for (j = 1; j <= i; j++) {
            // 计算 填充数组
            array[i][j] = array[i - 1][j - 1] + array[i - 1][j];
            // 打印余下的元素
            printf("%6d", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}
4. 更进一步的优化

既然是为了打印,那么在打印的时候读取上一行的内容,同时计算出当前行内容保存起来也是可以的。
所以,可以尝试用两个一维数组来实现进一步的优化。

#import <stdio.h>
#define line 10

int main(int argc, const char * argv[]) {
    //printf("%lu", sizeof(int));
    // 初始化 变量
    int i, j, n = line;
    // 初始化 数组
    // 两个数组用来保存两行数字
    int array1[line] = { 0 };
    int array2[line] = { 0 };
    
    int * pUp = array1; // 指向保存上一行数字的数组
    int * pDown = array2; // 指向保存当前行数组的数组
    int * p = NULL; // 空指针用来进行指针交换
    
    int index = 0; // 访问下标
    
    // 每行左右两边都是 1
    // 从第二行起,中间的每一个数是上一行里相邻两个数之和
    // 第 n 行 有 n 个数字
    // 因为第1行 第2行 均为已知
    // 所以 从第三行开始
    // 从第三行开始计算(i = 2)
    // 每一个空格的内容都是它左上方和上方两个元素之和
    int k;
    for (i = 0; i < n; i++) {
        // 打印每行前面的空格
        for (k = i; k < n - 1; k++) {
            printf("   ");
        }
        // 打印每行第一个元素
        printf("%6d", 1);
        *(pDown + index++) = 1;
        for (j = 1; j <= i; j++) {
            // 计算 填充数组
            *(pDown + index) = *(pUp + index - 1) + *(pUp + index);
            printf("%6d", *(pDown + index));
            index++;
        }
        index = 0;
        
        // 两个指针指向内容交换
        p = pUp;
        pUp = pDown;
        pDown = p;
        printf("\n");
    }
    return 0;
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 180,544评论 25赞 708
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 30,468评论 8赞 265
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 14,607评论 2赞 59
  • 凡人莫道仙家好, 牛郎无意酬鹊桥。 良辰美景作平常, 佳期又盼来年时。
    bb53503536bd阅读 188评论 0赞 1
  • 实例生命周期 每个vue实例在被创建之前都要经过一系列的初始化过程,例如,实习需要配置数据观测,编译模版,挂载实例...
    饥人谷_廖珍阅读 1,491评论 0赞 0

友情链接更多精彩内容