PY の 两种方法打印杨辉三角

方法一:临数相加等于中间夹值

这个方法是大多数人选择的做法吧,至少从逻辑来看,简单太多

以第三行 L 行为例(首行为0行),L[0] + L[1]L[1] + L[2]L[2] + L[3] 分别相加,可以取到下一行相夹的数,但最左和最右的  1  是没有关联到,需要我们自行添加

so,我们用列表生成式打印杨辉三角,如下:

def triangle(lines):
    L = [1]
    n = 0
    while n <= lines:
        yield L
        L = [1] + [L[i-1] + L[i] for i in range(1, len(L))] + [1]
        n = n + 1
        
print_triangle = triangle(8)

for line in print_triangle:
    print(line)

>>>
[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]

方法二:二项式系数 (恐数者慎翻-.-)

从图中可以看出,杨辉三角与二项式分解后各项的系数,一 一 对应 

二项式展开公式:

(a+b)^{n}=C_{n}^{0}a^{n}b^{0}+C_{n}^{1}a^{n-1}b^{1}+...+C_{n}^{n}a^{0}b^{n}

在此我们只关注二项式系数,可以得知,第 m 项的系数是:C_{n}^{m}

再来温习一遍排列组合中组合的公式:

 C_{n}^{m} = \frac{n!}{m!(n-m)!}

可以无脑将阶乘以递归形式:

def func(n):
    output = '1'
    for m in range(1, n):
        temp = fact(n) // (fact(m) * fact(n-m))
        output = output + ' ' + str(temp)
    return output + ' 1'

def fact(n):
    if n == 1:
        return 1
    return n * fact(n - 1)
    
res = func(4)
print(res)

>>>
1 4 6 4 1

不过这种折中递归,属于“弟中弟”的写法。

来一种不用递归的方法,观察  C_{4}^{} 的规律有:

C_{4}^{0} = 1

C_{4}^{1} = \frac{4!}{1!*(4-1)!}=1*\frac{4}{1}=C_{4}^{0}\frac{n-m+1}{m}(n=4,m=1)

C_{4}^{2} = \frac{4!}{2!*(4-2)!}=\frac{4*3}{1*2}=\frac{4}{1}*\frac{3}{2}=C_{4}^{1}\frac{n-m+1}{m}(n=4,m=2)

C_{4}^{3} = \frac{4!}{3!*(4-3)!}=\frac{4*3*2}{1*2*3}=\frac{4}{1}*\frac{3}{2}*\frac{2}{3}=C_{4}^{2}\frac{n-m+1}{m}(n=4,m=3)

最后一个,我们根据规律得出:C_{4}^{4}=C_{4}^{3}\frac{n-m+1}{m}(n=4,m=4)

用 python 将这个结论体现出来:

def calc(n):
    output = '1' 
    c = 1
    for m in range(1, n+1):
        c = c * (n-m+1) // m
        output = output + ' ' +str(c)
    return output

def generate_line(lines):
    n = 0
    while n <= lines:
        yield calc(n)
        n = n + 1

print_triangle = generate_line(8)
for line in print_triangle:
    print(line)

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

当然,题目还有更多有趣的解法,如果你有更简单的方法,就留言分享吧~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值