Python-Core-50-Courses/第07课:分支和循环结构的应用.md

166 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

## 第07课分支和循环结构的应用
通过上两节课的学习大家对Python中的分支和循环结构已经有了感性的认识。**分支和循环结构**的重要性不言而喻,它**是构造程序逻辑的基础**,对于初学者来说也是比较困难的部分。大部分初学者在学习了分支和循环结构后都能理解它们的用途和用法,但是遇到实际问题的时候又无法下手;**看懂别人的代码很容易,但是要自己写出同样的代码却又很难**。如果你也有同样的问题和困惑,千万不要沮丧,这只是因为你才刚刚开始编程之旅,**你的练习量还没有达到让你可以随心所欲的写出代码的程度**,只要加强编程练习,这个问题迟早都会解决的。下面我们就为大家讲解一些经典的案例。
### 经典小案例
#### 例子1寻找水仙花数。
> **说明**水仙花数也被称为超完全数字不变数、自恋数、自幂数、阿姆斯特朗数它是一个3位数该数字每个位上数字的立方之和正好等于它本身例如$ 153=1^3+5^3+3^3 $。
这个题目的关键是将一个三位数拆分为个位、十位、百位这一点利用Python中的`//`(整除)和`%`(求模)运算符其实很容易做到,代码如下所示。
```Python
"""
找出所有水仙花数
Version: 0.1
Author: 骆昊
"""
for num in range(100, 1000):
low = num % 10
mid = num // 10 % 10
high = num // 100
if num == low ** 3 + mid ** 3 + high ** 3:
print(num)
```
上面利用`//`和`%`拆分一个数的小技巧在写代码的时候还是很常用的。我们要将一个不知道有多少位的正整数进行反转,例如将`12345`变成`54321`,也可以利用这两个运算来实现,代码如下所示。
```Python
"""
正整数的反转
Version: 0.1
Author: 骆昊
"""
num = int(input('num = '))
reversed_num = 0
while num > 0:
reversed_num = reversed_num * 10 + num % 10
num //= 10
print(reversed_num)
```
#### 例子2百钱百鸡问题。
> **说明**:百钱百鸡是我国古代数学家[张丘建](https://baike.baidu.com/item/%E5%BC%A0%E4%B8%98%E5%BB%BA/10246238)在《算经》一书中提出的数学问题鸡翁一值钱五鸡母一值钱三鸡雏三值钱一。百钱买百鸡问鸡翁、鸡母、鸡雏各几何翻译成现代文是公鸡5元一只母鸡3元一只小鸡1元三只用100块钱买一百只鸡问公鸡、母鸡、小鸡各有多少只
```Python
"""
《百钱百鸡》问题
Version: 0.1
Author: 骆昊
"""
# 假设公鸡的数量为xx的取值范围是0到20
for x in range(0, 21):
# 假设母鸡的数量为yy的取值范围是0到33
for y in range(0, 34):
z = 100 - x - y
if 5 * x + 3 * y + z // 3 == 100 and z % 3 == 0:
print(f'公鸡: {x}只, 母鸡: {y}只, 小鸡: {z}只')
```
上面使用的方法叫做**穷举法**,也称为**暴力搜索法**,这种方法通过一项一项的列举备选解决方案中所有可能的候选项并检查每个候选项是否符合问题的描述,最终得到问题的解。这种方法看起来比较笨拙,但对于运算能力非常强大的计算机来说,通常都是一个可行的甚至是不错的选择,只要问题的解存在就能够找到它。
#### 例子3CRAPS赌博游戏。
> **说明**CRAPS又称花旗骰是美国拉斯维加斯非常受欢迎的一种的桌上赌博游戏。该游戏使用两粒骰子玩家通过摇两粒骰子获得点数进行游戏。简化后的规则是玩家第一次摇骰子如果摇出了7点或11点玩家胜玩家第一次如果摇出2点、3点或12点庄家胜玩家如果摇出其他点数则玩家继续摇骰子如果玩家摇出了7点庄家胜如果玩家摇出了第一次摇的点数玩家胜其他点数玩家继续摇骰子直到分出胜负。
```Python
"""
Craps赌博游戏
我们设定游戏开始时玩家有1000元的赌注
游戏结束的条件是玩家破产(输光所有的赌注)
Version: 0.1
Author: 骆昊
"""
from random import randint
money = 1000
while money > 0:
print(f'你的总资产为: {money}元')
go_on = False
# 下注金额必须大于0小于等于玩家总资产
while True:
debt = int(input('请下注: '))
if 0 < debt <= money:
break
# 第一次摇色子
# 用1到6均匀分布的随机数模拟摇色子得到的点数
first = randint(1, 6) + randint(1, 6)
print(f'\n玩家摇出了{first}点')
if first == 7 or first == 11:
print('玩家胜!\n')
money += debt
elif first == 2 or first == 3 or first == 12:
print('庄家胜!\n')
money -= debt
else:
go_on = True
# 第一次摇色子没有分出胜负游戏继续
while go_on:
go_on = False
current = randint(1, 6) + randint(1, 6)
print(f'玩家摇出了{current}点')
if current == 7:
print('庄家胜!\n')
money -= debt
elif current == first:
print('玩家胜!\n')
money += debt
else:
go_on = True
print('你破产了, 游戏结束!')
```
#### 例子4斐波那契数列。
> **说明**斐波那契数列Fibonacci sequence通常也被称作黄金分割数列是意大利数学家莱昂纳多·斐波那契Leonardoda Fibonacci在《计算之书》中研究在理想假设条件下兔子成长率问题而引入的数列因此这个数列也常被戏称为“兔子数列”。斐波那契数列的特点是数列的前两个数都是1从第三个数开始每个数都是它前面两个数的和按照这个规律斐波那契数列的前10个数是`1, 1, 2, 3, 5, 8, 13, 21, 34, 55`。斐波那契数列在现代物理、准晶体结构、化学等领域都有直接的应用。
```Python
"""
输出斐波那契数列前20个数
Version: 0.1
Author: 骆昊
"""
a, b = 0, 1
for _ in range(20):
a, b = b, a + b
print(a)
```
#### 例子5打印100以内的素数。
> **说明**素数指的是只能被1和自身整除的正整数不包括1
```Python
"""
输出100以内的素数
Version: 0.1
Author: 骆昊
"""
for num in range(2, 100):
# 假设num是素数
is_prime = True
# 在2到num-1之间找num的因子
for factor in range(2, num):
# 如果找到了num的因子num就不是素数
if num % factor == 0:
is_prime = False
break
# 如果布尔值为True在num是素数
if is_prime:
print(num)
```
### 简单的总结
还是那句话:**分支结构和循环结构非常重要**,是构造程序逻辑的基础,**一定要通过大量的练习来达到融会贯通**。刚才讲到的CRAPS赌博游戏那个例子可以作为一个标准如果你能很顺利的完成这段代码那么分支和循环结构的知识你就已经掌握了。