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