常规方法和运用指针的方法
前言
杨辉三角是一道很经典的编程题,从中可以学习很多细节的东西。
一
常规方法首先先观察杨辉三角的特点如下图,第一列全部都是 1对角线也如此全都是1。当行数>3
列数>2时每个数字等于其上一行数字和上一行前一列数字之和。例如第三行2 =1+1。同理下面数字有着相同规律。
这样就有一个大致思路对于这种数字很明显需要二维数组来描述,首先创建一个二维数组向里面填充数据,我以30x30二维数组为例。填充二维数组经典方法就是双for循环不多做解释。填充时候加入判断条件如果数组列数为1直接赋值为1,行数和列数相等也直接赋值为1。这样就填充好第一列和对角线的数据了,其次加入判断条件当数组行数大于等于第三行并且列数大于等于第二行(注意这里要同时满足)就可以进行计算。因为其他位置都初始化为0。所以不用担心对角线上数字进行运算的问题。
int main()
{
int n = 0;
scanf("%d", &n);
int arr[30][30] = { 0 };
int i = 0;
int j = 0;
for (i=0;i<n;i++)
{
for (j = 0; j <n; j++)
{
if (j == 0||i ==j )
{
arr[i][j] = 1;
}
if (i >= 2 && j >= 1)
{
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
print(arr,n);
return 0;
}
}
其次就是打印阶段,在这没有直接打印将其封装为函数打印 下图函数部分,将数组作为参数,传递给函数(数组传参传递的是首元素地址)函数也用30x30数组接受,打印也是经典的双for循环一行一行进行打印,但是由于第一行打印1个数据第二行打印2个数据是变量,内循环条件也需要变量注意一下然后直接打印就完成了。
void print(int arr[30][30], int n)
{
int i = 0;
int j = 0;
for (i = 0;i<n;i++)
{
for (j = 0;j<i+1;j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
完整代码如下
#include <stdio.h>
void print(int arr[30][30], int n)
{
int i = 0;
int j = 0;
for (i = 0;i<n;i++)
{
for (j = 0;j<i+1;j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int arr[30][30] = { 0 };
int i = 0;
int j = 0;
for (i=0;i<n;i++)
{
for (j = 0; j <n; j++)
{
if (j == 0||i ==j )
{
arr[i][j] = 1;
}
if (i >= 2 && j >= 1)
{
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
}
print(arr,n);
return 0;
}
二
下来介绍第二种,大家很疑惑为啥那么麻烦封装函数打印,为什么不直接打印,这里主要原因就是想让大家练习一下初阶指针,因为数组传参本质是传递首元素地址,地址那用整形指针来接受其实更加准确。数组填充部分其实跟上述一样不多做赘述,主要是函数部分需要讲解一下。由于传递出来的是首元素地址那么指针就指在数组的第一个元素。由于二维数组杨辉三角所需的数字我们已经在主函数内部进行填充,剩余部分数字都是零运用这个特点来进行打印是一个大体思路,还是双重循环,这里在提醒一下开始我们初始化时30x30的二维数组并且初始化为0,打印还是双循环类型只不过我这里用while,一行一行打印首先第一行,if判断如果指针解引用后不是0直接打印,加入计数器cout指针每次向后位移1个元素当计数器为30说明第一行打印完成,break跳出内层循环,开始第二行,后面接如此。
print(int* arr, int n)
{
int i = 0;
int j = 0;
int cout = 0;
for (i=0;i<n;i++)
{
while (1)
{
if (*arr != 0)
{
printf("d ", *arr);
}
arr++;
cout++;
if (cout == 30)
break;
}
printf("\n");
cout = 0;
}
}
第二种方法整个代码如下
#include <stdio.h>
print(int* arr, int n)
{
int i = 0;
int j = 0;
int cout = 0;
for (i=0;i<n;i++)
{
while (1)
{
if (*arr != 0)
{
printf("%5d", *arr);
}
arr++;
cout++;
if (cout == 30)
break;
}
printf("\n");
cout = 0;
}
}
int main()
{
int arr[30][30] = {0};
int n = 0;
scanf("%d", &n);
int i = 0;
int j = 0;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
if (j == 0)
{
arr[i][j] = 1;
}
if (i == j)
{
arr[i][j] = 1;
}
if (i >= 2 && j >= 1)
{
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
}
print(arr,n);
return 0;
}
欢迎各位来讨论有无优化的方法,感谢阅读。