目录
1.杨辉三角形定义
2.用数组实现10层的杨辉三角形
3.使用List泛型链表集合设计10层的杨辉三角形
(1)代码解释:
(2)算法中求余的作用
4.使用List泛型链表集合设计10层的等腰的杨辉三角形
1.杨辉三角形定义
杨辉三角是一个由数字排列成的三角形数表,其最本质的特征是它的两条边都是由数字1组成的,而其余的数则等于它上方的两个数之和。
杨辉三角有两种常用的表示形式。
2.用数组实现10层的杨辉三角形
程序使用嵌套的for循环创建一个2D数组,并根据行和列索引为其填充适当的值。
用于生成三角形的算法称为杨辉算法,这是一种使用仅使用上一行的元素计算杨辉三角的元素的高效方法。程序首先将三角形的前两行的所有元素设置为1。对于每后续行,程序将第一个和最后一个元素设置为1,并通过将上一行中上面的两个元素相加来计算剩余元素。
// 10层的杨辉三角形
namespace _150_3
{internal class Program{private static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);// 向数组中记录杨辉三角形的值int[][] Array_int = new int[10][]; //定义一个10行的二维数组for (int i = 0; i < Array_int.Length; i++) //遍历行数{Array_int[i] = new int[i + 1]; //定义二维数组的列数for (int j = 0; j < Array_int[i].Length; j++)//遍历二维数组的列数{if (i <= 1) //如果是数组的前两行{Array_int[i][j] = 1; //将其设置为1continue;}else{if (j == 0 || j == Array_int[i].Length - 1)//如果是行首或行尾Array_int[i][j] = 1;//将其设置为1elseArray_int[i][j] = Array_int[i - 1][j - 1] + Array_int[i - 1][j];//根据杨辉算法进行计算}}}// 输出杨辉三角形for (int i = 0; i < Array_int.Length; i++){for (int j = 0; j < Array_int[i].Length; j++)Console.Write("{0}\t", Array_int[i][j]);Console.WriteLine();}Console.ReadLine();}}
}
//运行结果:
/*
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1*/
3.使用List<int>泛型链表集合设计10层的杨辉三角形
// 使用List<int>泛型链表集合设计10层的杨辉三角形
namespace _150
{class Program{static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);int layer = 10;List<List<int>> pam = [];for (int i = 0; i < layer; i++){pam.Add([]);for (int j = 0; j <= i; j++){if (i == 0){pam[i].Add(1);}else if (i == 1){pam[i].Add(j == 0 ? 1 : 1);}else{pam[i].Add(j == 0 || j == i ? 1 : (pam[i - 1][j - 1] + pam[i - 1][j]) % 1000000007);}}}foreach (var row in pam){foreach (var num in row){Console.Write("{0}\t", num);}Console.WriteLine();}}}
}
//运行结果:
/*
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1*/
(1)代码解释:
- 首先定义了一个List<List<int>>泛型链表集合pam,用于存储杨辉三角形的每一层。
- 然后使用两个嵌套的for循环,分别遍历每一层和每一列,根据新的杨辉三角形规律计算每个位置的数字。
- 第一行只有一个元素1,第二行有两个元素1和1,从第三行开始的每行首尾元素为1,其余元素等于上一行其正上方相邻2元素和。
- 最后,使用foreach循环遍历链表集合pam,打印出每个列表中的每个数字,即为10层的杨辉三角形。
(2)算法中求余的作用
//为什么有这个求余?
pam[i].Add(j == 0 || j == i ? 1 : (pam[i - 1][j - 1] + pam[i - 1][j]) % 1000000007);
这个求余运算% 1000000007是用来避免整数溢出的。
在计算每个位置的数字时,如果直接进行加法运算,当数字变得非常大时,可能会超过整数的最大值,导致整数溢出。为了避免这个问题,我们使用了一个大数运算的方法,即将每个数字对一个很大的数进行求余运算,这样可以保证结果始终在一个较小的范围内,避免整数溢出。
这个求余运算的值1000000007是一个质数,选择一个质数作为求余运算的值可以保证运算结果的唯一性和周期性,即对于任意两个不同的正整数a和b,它们对1000000007取余的结果也是不同的,且a和b的和对1000000007取余的结果等于(a + b) % 1000000007,这保证了运算结果的正确性。
4.使用List<int>泛型链表集合设计10层的等腰的杨辉三角形
// 用泛型链表列设计的等腰的杨辉三角形
namespace _150_2
{class Program{static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);int layer = 10;List<List<int>> pam = [];for (int i = 0; i < layer; i++){pam.Add([]);for (int j = 0; j <= i; j++){if (i == 0){pam[i].Add(1);}else if (i == 1){pam[i].Add(j == 0 ? 1 : 1);}else{pam[i].Add(j == 0 || j == i ? 1 : (pam[i - 1][j - 1] + pam[i - 1][j]) % 1000000007);}}}int max_width = 0;foreach (var row in pam){max_width = Math.Max(max_width, row.Count);}for (int i = 0; i < layer; i++){int width = pam[i].Count;int padding = (max_width - width) * 8 / 2;Console.Write(new string(' ', padding));for (int j = 0; j < width; j++){Console.Write(pam[i][j].ToString().PadLeft(8));//每个数字8位}Console.WriteLine();}}}
}
//运行结果:
/*11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 11 6 15 20 15 6 11 7 21 35 35 21 7 11 8 28 56 70 56 28 8 11 9 36 84 126 126 84 36 9 1*/
代码解释:
- 首先计算出杨辉三角形的最大宽度max_width,即最大行数。
- 然后在打印每一行时,计算出该行需要填充的空格数padding,即最大宽度减去当前行的宽度,然后除以2(因为左右两侧都需要填充空格)。
- 使用Console.Write(new string(' ', padding))输出填充的空格。
- 接着使用嵌套的foreach循环遍历链表集合pam中的每个数字,并使用Console.Write输出每个数字及占位。
- 最后使用Console.WriteLine()换行,以便开始下一行的输出。