轨道
/
Python
Python
/
练习
/
帕斯卡三角形
帕斯卡三角形

帕斯卡三角形

中等

简介

天气这么好,你却一点也不想在教室里待上一个小时。 你有些烦闷地走进教室,发现黑板上有一个形状奇特却让人莫名舒服的三角形。 在等数学老师到来的时候,你忍不住注意到这个三角形里的一些规律:最外层的值全是 1,每一行都比上一行多一个值,而且整个三角形是对称的。 太奇怪了!

你坐下没多久,老师就走进教室,解释说这个三角形就是著名的帕斯卡三角。

在接下来的一小时里,老师揭示了这个三角形里藏着的一些奇妙之处:

  • 可以用它来计算从 N 个值中选出 K 个元素有多少种选法。
  • 它包含了斐波那契数列。
  • 如果你把奇数和偶数染上不同的颜色,就会得到一个美丽的图案,叫做谢尔宾斯基三角。

老师请你和同学们去查一查它的其他用途,并保证这样的用途还有很多很多! 就在这时,学校的铃声响了。 你意识到,过去的一小时里,你完全沉浸在帕斯卡三角的学习中。 你迅速从包里拿出笔记本电脑,走到外面,准备好好享受阳光,_也_享受帕斯卡三角的奇妙。

说明

你的任务是输出帕斯卡三角的前 N 行。

帕斯卡三角是一个由正整数构成的三角形。

在帕斯卡三角中,一行里值的个数等于该行的行号(行号从 1 开始)。 因此,第一行有一个值,第二行有两个值,依此类推。

第一行(最上面一行)只有一个值:1。 后面每一行的值,是把上一行中当前位置左右两侧紧挨着的数字相加得到的。

如果上一行中当前位置的左侧或右侧没有值(这种情况只出现在最左边和最右边的位置上),就把那个位置的值当作 0(相当于在求和时“忽略”它)。

示例

我们来看看帕斯卡三角的前 5 行:

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1

最上面的一行只有一个值,就是 1。

最左边和最右边的值都只有一个相邻位置需要考虑,分别是它右侧和左侧的那个位置。 由于最上面的值是 1,由此可知所有最左边和最右边的值也都是 1。

其他值都有两个位置需要考虑。 例如,第五行(1 4 6 4 1)中间的值是 6,因为上一行中它左右两侧的值都是 3:

本练习在 Python 中如何实现:递归

本练习旨在让你使用 recursion 来完成,而不是使用循环。 递归函数就是调用自身的函数,在解决那些用自身来定义的问题时很有用。 为了避免无限递归(更准确地说,是为了避免栈溢出),我们会用到所谓的“基本情况”。 当到达基本情况时,会返回一个非递归的值,于是上一次函数调用得以求解并返回它的值,依此类推,沿调用栈一路回溯,直到第一次函数调用返回答案。 我们可以写一个递归函数来求 5!(也就是 5 * 4 * 3 * 2 * 1)的结果,就像这样:

def factorial(number):
  if number <= 1:  # base case
    return 1

  return number * factorial(number - 1) # recursive case

print(factorial(5)) # returns 120

最后要说明的是,Python 限制了递归调用的次数(默认 1000 次),也不会对尾递归进行优化。

异常信息

有时需要抛出异常。 这样做时,一定要附上有意义的错误信息,说明错误的来源。 这能让代码更易读,也大大有助于调试。 如果你知道错误来源属于某种类型,可以选择抛出内置错误类型中的一种,但依旧要附上有意义的信息。

本练习特别要求:如果传给rows()函数的是负数,就要用raise语句“抛出”多个ValueErrors。 只有既raise了exception、又附带了信息,测试才会通过。

要抛出带信息的ValueError,把信息作为实参传给exception类型:

# if the rows function is passed a negative number.
raise ValueError("number of rows is negative")
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Python Exercism

准备好开始 帕斯卡三角形 了吗?

注册 Exercism,借助 17 个概念146 个练习 和真人导师指导,学习并掌握 Python,全部免费。