目录
杨辉三角
杨辉三角,是二项式系数在三角形中的一种几何排列。在欧洲,这个表叫做帕斯卡三角形。它把二项式系数图形化,把组合数内在的一些代数性质直观地从图形中体现出来,是一种离散型的数与形的结合
解法一(常规法)
将三角形形状破坏,元素前面的空格取消后,图形变为了一个下三角矩阵
1
1 1
1 2 1
1 3 3 1
...
这时我们发现,对于这个矩阵,正对角线和第一列都为1,其余数字为上一行同列与上一行上一列数字之和。
代码如下:
int dimension = 0;//维度
int arr[10][10] = { 0 };//初始化二阶矩阵
int i=0,j=0;
scanf("%d", &dimension);
for (i = 0; i < dimension; i++)
{
for (j = 0; j <= i; j++)//行,等于号不能少,第一行循环不进去
{
if (i == j || j == 0)//对角线和第一列为1
arr[i][j] = 1;
else
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
for (i = 0; i < dimension; i++)
{
for (j = dimension - 1 - i; j >= 0; j--)
{
printf(" ");//打印空格
}
for (j = 0; j <= i; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
解法2(二维初始化外层法)
第二种解法与第一种解法的区别在于,我们不对对角线和第一列进行1的初始化。
思路为我们在我们操作的矩阵外面在加一层不打印的矩阵,接着我们将这个外层矩阵的第一行第一列和第一行第二列分别初始化为0,1,这样大家只需要操作里层矩阵,也就是从第二行第二列,只需要进行三角和即可。
代码如下:
int main()
{
int i, j, n = 0;
int a[100][100] = { 0,1 };
scanf("%d", &n);
for (i = 1; i < n; i++)
{
for (j = 1; j <= i; j++)
{
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
printf("%5d", a[i][j]);
}
printf("\n");
}
return 0;
}
0 1 # # # 我们将空格用#代替
# 1 1 # #
# 1 2 1 #
# 1 3 3 1 我们只需操作里层就行
解法3(一维数组法)
这种方法也就是使用一维数组,我们可以在打印完一行后用提前保存的临时变量将行数初始化,进行打印第二行,或是初始化两个一维数组,分别初始化为1,0,用初始化1的数组对另一个数组进行传参,打印初始化为零的数组,只需注意换行就行,达到视觉上二维的效果。
int main()
{
int i, j, n, k, t;
int arr[21]={0,1}; //保存一行
printf("请输入杨辉三角形的行数(1 ~ 20):");
scanf("%d",&n);
for( i = 1; i <= n; i++)
{
for( j = 0; j < n - i; j++)
printf(" ");
t = 0;//0的作用想象外层一圈0,为保证每一行的第一个数字为1
for( j = 1; j <= i; j++)
{
k = Buf[j];
Buf[j] = t + k; //三角和计算
t = k;
printf("%d ", Buf[j]);
}
printf("\n");
}
return 0;
}
三角和的计算我们很容易得出,对于这个0的作用我们在一次作详细讲解
0 1是我们数组的初始数据
0 1 0 1 1 0 1 1 2
那么我们的打印就为
0(t) 1(k) 0 1(k) 0 1
1(arr[1]) -> 0(t) 1(t') 0(k') -> 0 1(k)
1(arr[1])这个时候t变为k 1(arr[2]) 0(t) 1(t') 1(k')(t'') 0(k'')
0 1 2 1(arr[3])
解法四(公式法)
公式法
- 第n行的数字有n项。
- 第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。
根据这两个规则我们可以根据公式法得出每行每列的数字
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 1, h;
int i, j;
scanf("%d", &h);
printf("1\n");
for (i = 2; i <= h; num = 1, i++) // 行数 i 从 2 到层高
{
printf("1 "); //
for (j = 1; j <= i - 2; j++) // 列位置 j 绕过第一个直接开始循环
printf("%d ", (num = (i - j) * num / j));
printf("1\n"); // 最后一个 1,换行
}
return 0;
解法5(递归)
类似于fib数列,这个我就不详说了看代码
#include <stdio.h>
int Tri(int i, int j) //函数的返回值可以为float或者long,当然你的维度不大的话int就可
{
return ( i == j || j == 1) ? 1 : Tri( i - 1, j - 1 ) + Tri( i - 1, j );
注意这里j为1不为零,模拟矩阵对角线和第一列
}
int main()
{
int i, j, n;
scanf("%d", &n);
for( i = 1; i <= n; i++)
{
for( j = 0; j < n - i; j++) //空格循环
printf(" ");
for( j = 1; j <= i; j++)
printf("%d ", Tri(i, j)); //计算并输出杨辉三角形
printf("\n");
}
return 0;
}
这种方法不需要创建数组