通过上两节课的学习,⼤家对
Python
中的分⽀和循环结构已经有了感性的认识。
分⽀和循环结构
的重要 性不⾔⽽喻,它是构造程序逻辑的基础
,对于初学者来说也是相对困难的部分。⼤部分初学者在学习了 分⽀和循环结构后都能理解它们的⽤途和⽤法,但是遇到实际问题的时候⼜⽆法下⼿;看懂别⼈的代码
很容易,但是要⾃⼰写出同样的代码却⼜很难
。如果你也有同样的问题和困惑,千万不要沮丧,这只是因为你才刚刚开始编程之旅,你的练习量还没有达到让你可以随⼼所欲的写出代码的程度
,只要加强编程练习,这个问题迟早都会解决的。下⾯我们就为⼤家讲解⼀些经典的案例。
经典⼩案例
例⼦
1
:寻找⽔仙花数。
说明
:⽔仙花数也被称为超完全数字不变数、⾃恋数、⾃幂数、阿姆斯特朗数,它是⼀个
3
位数,
该数字每个位上数字的⽴⽅之和正好等于它本身,例如:
1
3
+ 5
3
+ 3
3
= 153
。
这个题⽬的关键是将⼀个三位数拆分为个位、⼗位、百位,这⼀点利⽤
Python
中的
//
(整除)和
% (求模)运算符其实很容易做到,代码如下所示。
"""
找出所有⽔仙花数
"""
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
,也可以利⽤这两个运算来实现,代码如下所示。
"""
正整数的反转
"""
num = int(input('num = '))
reversed_num = 0
while num > 0:
reversed_num = reversed_num * 10 + num % 10
num //= 10
print(reversed_num)
例⼦
2
:百钱百鸡问题。
说明
:百钱百鸡是我国古代数学家
张丘建
在《算经》⼀书中提出的数学问题:鸡翁⼀值钱五,鸡
⺟⼀值钱三,鸡雏三值钱⼀。百钱买百鸡,问鸡翁、鸡⺟、鸡雏各⼏何?翻译成现代⽂是:公鸡
5
元⼀只,⺟鸡
3
元⼀只,⼩鸡
1
元三只,⽤
100
块钱买⼀百只鸡,问公鸡、⺟鸡、⼩鸡各有多少
只?
"""
《百钱百鸡》问题
"""
# 假设公鸡的数量为x,x的取值范围是0到20
for x in range(0, 21):
# 假设⺟鸡的数量为y,y的取值范围是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}只')
上⾯使⽤的⽅法叫做
穷举法
,也称为
暴⼒搜索法
,这种⽅法通过⼀项⼀项的列举备选解决⽅案中所有可能的候选项并检查每个候选项是否符合问题的描述,最终得到问题的解。这种⽅法看起来⽐较笨拙,但对于运算能⼒⾮常强⼤的计算机来说,通常都是⼀个可⾏的甚⾄是不错的选择,只要问题的解存在就能够找到它。
例⼦
3
:
CRAPS
赌博游戏。
说明
:
CRAPS
⼜称花旗骰,是美国拉斯维加斯⾮常受欢迎的⼀种的桌上赌博游戏。该游戏使⽤两
粒骰⼦,玩家通过摇两粒骰⼦获得点数进⾏游戏。简化后的规则是:玩家第⼀次摇骰⼦如果摇出
了
7
点或
11
点,玩家胜;玩家第⼀次如果摇出
2
点、
3
点或
12
点,庄家胜;玩家如果摇出其他点数
则玩家继续摇骰⼦,如果玩家摇出了
7
点,庄家胜;如果玩家摇出了第⼀次摇的点数,玩家胜;其
他点数玩家继续摇骰⼦,直到分出胜负。
"""
Craps赌博游戏
我们设定游戏开始时玩家有1000元的赌注
游戏结束的条件是玩家破产(输光所有的赌注)
"""
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
。斐波那契数列在现代物理、准晶体结构、化学等
领域都有直接的应⽤。
"""
输出斐波那契数列前20个数
"""
# 前两个数都是1
a, b = 1, 1
print(a, b, end=' ')
# 通过递推公式算出后⾯的18个数
for _ in range(18):
a, b = b, a + b
print(b, end=' ')
例⼦
5
:打印素数。
说明
:素数指的是只能被
1
和⾃身整除的正整数(不包括
1
)。
"""
输出100以内的素数
"""
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)