前言
在2022年2月之前,这篇博客提供的解决标题问题的方法仅仅只有下文中的方法一。我于2022年2月更新了解决问题的方法二。相比方法一,方法二是更加符合人类逻辑的,而方法一不过是通过一个统一的数学表达式将杨辉三角中每一个位置的数值表示出来,实现上较为容易,但是难以推导出表达式。
1 方法一
首先,我们需要知道杨辉三角第i行,第j列元素的计算公式:
C
(
i
,
j
)
=
(
i
−
1
)
!
(
j
−
1
)
!
(
i
−
j
)
!
C(i,j)=\frac{(i-1)!}{(j-1)!(i-j)!}
C(i,j)=(j−1)!(i−j)!(i−1)!
知道这个之后,就可以看出,杨辉三角形求解的最基本方法实际上就是利用阶乘。因此我们可以直接定义一个函数来计算阶乘,然后再计算每个元素。最后,进行格式化输出。
1.1 代码
首先,定义一个阶乘函数(递归):
def factorial(n):#阶乘函数
if n == 0:
return 1
elif n > 0:
return n*factorial(n-1)
else:
print("Math error")
然后,再计算每一行元素,并将这一行的数值存入一个列表lst中,再将这个列表的数值复制到最后要输出的结果列表result中:
def Yanghui_triangle(m):
# 建立一个空列表,并根据传入的杨辉三角的层数m,在该列表中建立m个元素
# 第m个元素(从一开始)对应于杨辉三角的第m行元素的集合
result = []
for f in range(m):
result.append(1)
# result = [1 for x in range(m)]上面三行可以这样实现
# 建立一个空列表,用于存储生成的每一行的元素
lst = []
# i为行数,j为列数
for i in range(1, m + 1):
for j in range(1, i + 1):
element = factorial(i - 1) / (factorial(j - 1) * factorial(i - j))
lst.append(element)
# 这里使用的是浅拷贝
# 因为每计算一行lst的值都会改变如果仅仅只是赋值是不行的
result[i - 1] = lst.copy()
lst.clear() # 清空当前的lst
return result
如果不了解使用浅拷贝的原因,可以看看runoob网站上的解答,这真的是一个很好的神仙网站:link
最后进行杨辉三角阶数的输入,并格式化输出:
n = int(input("please input the number of layer:"))
triangle = Yanghui_triangle(n)
for i in range(1, n+1):
print((n-i)*'\t', end='')
for j in range(1, i+1):
print("%d" % triangle[i-1][j-1], end='\t\t')
print('\n')
结果图样:
2 方法二
方法二的实现是回到了杨辉三角直观上的理解。就像大家找规律一样,我们会发现:
1. 每个数等于其上方两数之和
2. 数字1在元素位置行数与列数相等(i == j)或每行第一个(j == 1)的时候出现
(其他诸如每一行元素对称等规律也不赘述了,不涉及的实现的原理)。基于这两点我们就可以进行递归函数的编写了。
2.1 代码
递归函数的编写:
def Yanghui_triangle(i, j):
if j == 1 or i == j:
return 1
else:
return Yanghui_triangle(i - 1, j - 1) + Yanghui_triangle(i - 1, j)
这样递归函数会返回对应位置的数值(方法一的函数是将所有元素生成并存储在一张二维列表中再进行格式化输出的),因此,格式化输出代码也会有一些改变:
n = int(input("please input the number of layer:"))
for i in range(1, n + 1):
print((n - i) * '\t', end='')
for j in range(1, i + 1):
print("%d" % Yanghui_triangle(i, j), end='\t\t')
print('\n')
输出结果与方法一的一样。
注意
代码不一定会是最简洁的。其实这一直是我在学校学习python过程中的遗留问题。在学校时,为了高速地完成作业,仅仅快速的写完方法一就没有深究下去了(其实在写之前就有了方法二的思路但是一直没有实现)。在2022年新年期间终于能够静下心来写写其他的东西了。