iOS面试

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

2018-11-16  本文已影响7人  寒山半秋
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;
}
上一篇下一篇

猜你喜欢

热点阅读