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;
}