A place for study and research

Python 100 Days Day05 Constructing Program Logic

|

author: jackfrued

構造程序邏輯

學完前面的幾個章節後,我覺得有必要在這里帶大家做一些練習來鞏固之前所學的知識,雖然迄今為止我們學習的內容只是Python的冰山一角,但是這些內容已經足夠我們來構建程序中的邏輯。對於編程語言的初學者來說,在學習了Python的核心語言元素(變量、類型、運算符、表達式、分支結構、循環結構等)之後,必須做的一件事情就是嘗試用所學知識去解決現實中的問題,換句話說就是鍛煉自己把用人類自然語言描述的算法(解決問題的方法和步驟)翻譯成Python代碼的能力,而這件事情必須通過大量的練習才能達成。

我們在本章為大家整理了一些經典的案例和習題,希望通過這些例子,一方面幫助大家鞏固之前所學的Python知識,另一方面幫助大家了解如何建立程序中的邏輯以及如何運用一些簡單的算法解決現實中的問題。

經典的例子

  1. 尋找水仙花數

    說明:水仙花數也被稱為超完全數字不變數、自戀數、自冪數、阿姆斯特朗數,它是一個3位數,該數字每個位上數字的立方之和正好等於它本身,例如:$1^3 + 5^3+ 3^3=153$。

    """
    找出所有水仙花數
       
    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: 駱昊
    """
       
    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點,莊家勝;如果玩家搖出了第一次搖的點數,玩家勝;其他點數,玩家繼續要骰子,直到分出勝負。

    """
    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)在《計算之書》中提出一個在理想假設條件下兔子成長率的問題而引入的數列,所以這個數列也被戲稱為"兔子數列"。斐波那契數列的特點是數列的前兩個數都是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)。

上面練習的參考答案在本章對應的代碼目錄中,如果需要幫助請讀者自行查看參考答案。

Comments