第07課:分支和循環結構的應用
通過上兩節課的學習,大家對Python中的分支和循環結構已經有了感性的認識。分支和循環結構的重要性不言而喻,它是構造程序邏輯的基礎,對於初學者來說也是比較困難的部分。大部分初學者在學習了分支和循環結構后都能理解它們的用途和用法,但是遇到實際問題的時候又無法下手;看懂別人的代碼很容易,但是要自己寫出同樣的代碼卻又很難。如果你也有同樣的問題和困惑,千萬不要沮喪,這只是因為你才剛剛開始編程之旅,你的練習量還沒有達到讓你可以隨心所欲的寫出代碼的程度,只要加強編程練習,這個問題遲早都會解決的。下面我們就為大家講解一些經典的案例。
經典小案例
例子1:尋找水仙花數。
說明:水仙花數也被稱為超完全數字不變數、自戀數、自冪數、阿姆斯特朗數,它是一個3位數,該數字每個位上數字的立方之和正好等於它本身,例如:$ 153=13+53+3^3 $。
這個題目的關鍵是將一個三位數拆分為個位、十位、百位,這一點利用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
,也可以利用這兩個運算來實現,代碼如下所示。
"""
正整數的反轉
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:百錢百雞問題。
說明:百錢百雞是我國古代數學家張丘建在《算經》一書中提出的數學問題:雞翁一值錢五,雞母一值錢三,雞雛三值錢一。百錢買百雞,問雞翁、雞母、雞雛各幾何?翻譯成現代文是:公雞5元一只,母雞3元一只,小雞1元三只,用100塊錢買一百只雞,問公雞、母雞、小雞各有多少只?
"""
《百錢百雞》問題
Version: 0.1
Author: 駱昊
"""
# 假設公雞的數量為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元的賭注
游戲結束的條件是玩家破產(輸光所有的賭注)
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
。斐波那契數列在現代物理、准晶體結構、化學等領域都有直接的應用。
"""
輸出斐波那契數列前20個數
Version: 0.1
Author: 駱昊
"""
a, b = 0, 1
for _ in range(20):
a, b = b, a + b
print(a)
例子5:打印100以內的素數。
說明:素數指的是只能被1和自身整除的正整數(不包括1)。
"""
輸出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賭博游戲那個例子可以作為一個標准,如果你能很順利的完成這段代碼,那么分支和循環結構的知識你就已經掌握了。