Repetition Structures¶
Introduction¶
電腦最會做的事,就是重複的事情,所以這裡要跟你介紹迴圈(Loop),迴圈可以讓我們重複執行一段程式碼,而不用一行一行的寫出來。
如果你要印 \(100\) 次 Hello World!
,你會怎麼做呢?
你會真的寫 \(100\) 行嗎?當然不會,不然你會氣死,然後把電腦砸了。
For Loop¶
首先,我們來看看 for
迴圈的用法。並舉個簡單的例子,印出 \(1\) 到 \(5\):
ouput | |
---|---|
range
,這個函式可以產生一個數列,並且可以指定起始值、結束值、間隔值。這個函式的用法如下:
如果只有一個參數,那就是結束值,起始值預設為 \(0\),間隔值預設為 \(1\)。
range(start=0, stop, step=1)
並且注意,stop
是不包含在數列中的。
Foreach¶
舉個例子,我想把字串 "Speed_of_Light"
中的每個字元都印出來。
ouput | |
---|---|
這裡的迴圈更接近概念上的 Foreach,每次迴圈都會取出字串中的一個字元,並且將他放到 c
中,這個概念請你記起來。
Break and Continue¶
再舉個例子,計算 \(\sum_{i=1}^n{i}=1+2+\cdots+n\)
input | |
---|---|
ouput | |
---|---|
接下來,跟你介紹 break
與 continue
,這兩個關鍵字可以用來控制迴圈的執行。
break
可以用來強制跳出迴圈,而 continue
則是強制跳到下一次迴圈。
ouput | |
---|---|
可以發現,i == 5
的時候,迴圈就被強制中斷了。
ouput | |
---|---|
可以發現,5
被跳過了。
Nested Loop¶
接著介紹巢狀迴圈(Nested Loop),也就是迴圈裡面還有迴圈。做個比喻的話,如果是兩層的迴圈,就像是時針與分針,內層迴圈每跑一圈,外層迴圈才跑一格。
我們來印一個直角三角形吧,輸入一個數字 \(n\),印出 \(n\) 層的直角三角形,將最頂端的那一層編號為 \(0\),最底端的那一層編號為 \(n-1\),其中第 \(i\) 層有 \(i+1\) 個星星 *
。
我稱內層的迴圈叫做 j
迴圈,外層的迴圈叫做 i
迴圈。 j
迴圈控制每一層的星星數量,而 i
迴圈則控制總共有幾層。每一層的星星數量都是 i + 1
,最後會換行。
input | |
---|---|
再來看一個經典的例子,九九乘法表。
i
控制列(Row),j
控制行(Column),每一列的數字都是 i
,每一行的數字都是 j
,所以 i * j
就是相應的乘積。
熱身完了,來看一個稍微複雜的例子,輸入一個數字,判斷他是不是質數。
這個例子會是等等更複雜的例子的基礎,所以請仔細看。
n
如果可以整除 1
與自己以外的數字,那就不是質數,我們可以用 break
來強制跳出迴圈,避免不必要的計算。
我們把問題用得更複雜,輸入一個數字 \(n\),輸出在 \([1, n]\) 之間最大的質數。
在這裡介紹如何讓 range
倒著數回來。
i
列舉 \([n, 1]\) 的數字,而 j
列舉 \([2, i-1]\) 的數字,如果 i
可以整除 j
,那就不是質數,馬上跳出內層 j
迴圈,繼續列舉下一個數字。如果 i
是質數,那就印出來,並且跳出外層 i
迴圈。
請你仔細端詳這兩個例子中強調的行數。
@EditTime : 2024-01-30 16:33
While loop¶
接著來介紹 while
迴圈,他的使用場景是當你不知道迴圈要執行幾次的時候,就可以用 while
迴圈,但是別寫出無窮迴圈(Infinite Loop)喔。
但在往下之前,先來看如何用 while
迴圈來印出 \(1\) 到 \(5\)。
ouput | |
---|---|
回顧一下 for loop,你可以發現邏輯其實一樣。
當條件成立的時候,就會執行迴圈,直到條件不成立。
再舉一個例子,輸入正整數 \(n\),輸出 \(n!\)
但目前這兩個例子無法看出 while
的魅力,因為你都知道迴圈什麼時候會結束,所以跟你介紹一個經典問題:
是指對於每一個正整數,如果它是奇數,則對它乘3再加1,如果它是偶數,則對它除以2,如此循環,最終都能夠得到1。
那我們要寫的程式是,輸入一個正整數 \(n\),輸出他會在幾步後變成 \(1\)。
依照定義,我們可以寫出以下程式碼:
ouput | |
---|---|
再來介紹一個經典的例子,輸入一個正整數 \(n\gt 1\),輸出 \(n\) 的質因數分解。
請你先自己想一下,再看看參考程式碼。
Example
內層的 while
迴圈會一直執行,直到 n
不是 factor
的倍數為止。外層的 while
迴圈則是列舉所有的質因數,直到 n
變成 \(1\) 為止。
題外話,當初遇到這個題目的時候,想了一下結果一次就AC,是很有成就感的一件事,所以也請你好好努力,逐步培養自信,你也可以的。
@EditTime : 2024-01-30 17:55
Bonus: for ... else and while ... else¶
for
與 while
迴圈都可以搭配 else
來使用,當迴圈正常結束的時候(沒有 break
),就會執行 else
。
to be continued...
Practice¶
Itsa - [C_MM03-易] 兩數總和
Itsa - [C_MM33-易] 找1~N的完美數
Reference code
這是暴力解,會TLE,下一章會介紹如何最佳化, 但如果使用 C++ 的話,相同邏輯的程式碼是可以AC的。Itsa - [C_MM34-易] 因數問題
Reference code
@EditTime : 2024-01-30 18:40
Assignment¶
Itsa - [C_MM21-易] 算階乘
Itsa - [C_MM25-易] 計算正整數被3整除之數值之總和
Itsa - [C_MM27-易] 計算兩整數間所有整數的總和
Itsa - [C_MM28-易] 計算1到N之間屬於5和7的倍數
Itsa - [C_MM29-易] 最大質數問題
Itsa - [C_MM30-易] 質數判別
Itsa - [C_MM40-易] 1~N之間的總和
Itsa - [C_MM49-易] 連續1的倍數
Itsa - [C_ST09-易] 星號矩形輸出
Itsa - [C_ST11-易] 星號菱形輸出
Itsa - [C_ST14-易] 數字直角三角形輸出
@EditTime : 2024-01-30 21:51