Python-100-Days/Day01-15/05.构造程序逻辑.md

130 lines
6.3 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.

## 构造程序逻辑
学完前面的几个章节后我觉得有必要在这里带大家做一些练习来巩固之前所学的知识虽然迄今为止我们学习的内容只是Python的冰山一角但是这些内容已经足够我们来构建程序中的逻辑。对于编程语言的初学者来说在学习了Python的核心语言元素变量、类型、运算符、表达式、分支结构、循环结构等之后必须做的一件事情就是尝试用所学知识去解决现实中的问题换句话说就是锻炼自己把用人类自然语言描述的算法解决问题的方法和步骤翻译成Python代码的能力而这件事情必须通过大量的练习才能达成。
我们在本章为大家整理了一些经典的案例和习题希望通过这些例子一方面帮助大家巩固之前所学的Python知识另一方面帮助大家了解如何建立程序中的逻辑以及如何运用一些简单的算法解决现实中的问题。
### 经典的例子
1. 寻找**水仙花数**。
> **说明**水仙花数也被称为超完全数字不变数、自恋数、自幂数、阿姆斯特朗数它是一个3位数该数字每个位上数字的立方之和正好等于它本身例如$1^3 + 5^3+ 3^3=153$。
```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: 骆昊
"""
for x in range(0, 20):
for y in range(0, 33):
z = 100 - x - y
if 5 * x + 3 * y + z / 3 == 100:
print('公鸡: %d只, 母鸡: %d只, 小鸡: %d只' % (x, y, z))
```
上面使用的方法叫做**穷举法**,也称为**暴力搜索法**,这种方法通过一项一项的列举备选解决方案中所有可能的候选项并检查每个候选项是否符合问题的描述,最终得到问题的解。这种方法看起来比较笨拙,但对于运算能力非常强大的计算机来说,通常都是一个可行的甚至是不错的选择,而且问题的解如果存在,这种方法一定能够找到它。
3. **CRAPS赌博游戏**
> **说明**CRAPS又称花旗骰是美国拉斯维加斯非常受欢迎的一种的桌上赌博游戏。该游戏使用两粒骰子玩家通过摇两粒骰子获得点数进行游戏。简单的规则是玩家第一次摇骰子如果摇出了7点或11点玩家胜玩家第一次如果摇出2点、3点或12点庄家胜其他点数玩家继续摇骰子如果玩家摇出了7点庄家胜如果玩家摇出了第一次摇的点数玩家胜其他点数玩家继续要骰子直到分出胜负。
```Python
"""
Craps赌博游戏
我们设定玩家开始游戏时有1000元的赌注
游戏结束的条件是玩家输光所有的赌注
Version: 0.1
Author: 骆昊
"""
from random import randint
money = 1000
while money > 0:
print('你的总资产为:', money)
needs_go_on = False
while True:
debt = int(input('请下注: '))
if 0 < debt <= money:
break
first = randint(1, 6) + randint(1, 6)
print('玩家摇出了%d点' % first)
if first == 7 or first == 11:
print('玩家胜!')
money += debt
elif first == 2 or first == 3 or first == 12:
print('庄家胜!')
money -= debt
else:
needs_go_on = True
while needs_go_on:
needs_go_on = False
current = randint(1, 6) + randint(1, 6)
print('玩家摇出了%d点' % current)
if current == 7:
print('庄家胜')
money -= debt
elif current == first:
print('玩家胜')
money += debt
else:
needs_go_on = True
print('你破产了, 游戏结束!')
```
###有用的练习
1. 生成**斐波那契数列**的前20个数。
> **说明**斐波那契数列Fibonacci sequence又称黄金分割数列是意大利数学家莱昂纳多·斐波那契Leonardoda Fibonacci在《计算之书》中提出一个在理想假设条件下兔子成长率的问题而引入的数列所以这个数列也被戏称为&quot;兔子数列&quot;。斐波那契数列的特点是数列的前两个数都是1从第三个数开始每个数都是它前面两个数的和形如1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...。斐波那契数列在现代物理、准晶体结构、化学等领域都有直接的应用。
2. 找出10000以内的**完美数**。
> **说明**完美数又称为完全数或完备数它的所有的真因子即除了自身以外的因子的和即因子函数恰好等于它本身。例如6$6=1+2+3$和28$28=1+2+4+7+14$)就是完美数。完美数有很多神奇的特性,有兴趣的可以自行了解。
3. 输出**100以内所有的素数**。
> **说明**素数指的是只能被1和自身整除的正整数不包括1
上面练习的参考答案在本章对应的代码目录中,如果需要帮助请读者自行查看参考答案。