<style> .reveal .slides { font-size: 38px; } </style> # 南大附中資訊研究社 NFIRC 1st ## 第 5 次社課講義 2023/12/06 主講:ShiYu --- ## 課前準備 - 開電腦 登DC ZJ... - 南部資研社聯合寒訓參加意願調查 ![qr.ioi.tw (4)](https://hackmd.io/_uploads/S1xf68sSa.png) ---- ### 行政組工作人員招募 ![qr.ioi.tw (3)](https://hackmd.io/_uploads/rksJ6LjBT.png) --- ## 今日課程內容 - 迴圈複習 - 陣列 Array - 迴圈與陣列的結合 - 字串 - 必做題 ---- # 重要提醒 下次社課為「期末練習賽👨🏻‍💻」+「聚餐🍕」 這次社課學完記得要回去複習過一遍之前教過的所有內容 資源都幫大家彙整在這了 > [NFIRC 資源彙整](https://hackmd.io/@NFIRC/resource) 多多寫題單 期末賽的題目只要你有寫題單就會了 --- ## 複習第 4 次社課內容 - 迴圈 - while 迴圈 - for 迴圈 - 迴圈控制 - continue - break ---- ## while 迴圈 當條件成立時 重複執行直到條件不成立 ```txt= while(條件成立時) { 重複執行這段程式碼 } ``` 條件不成立時 電腦會退出迴圈並接著執行下面的程式 ---- ## 用 while 迴圈說 100 次 hello ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int t = 100; while(t--) { cout << "hello\n"; } return 0; } ``` ---- ## 用 while 迴圈讀入 n 個數字並加總 輸入 ```txt 5 10 40 20 80 50 ``` 程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n, a, sum = 0; cin >> n; while(n--) { cin >> a; sum += a; } cout << sum << "\n"; return 0; } ``` ---- ## 重要技巧 EOF 輸入 ```txt 10 40 20 80 50 ``` 程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n, sum = 0; while(cin >> n) { sum += n; } cout << sum << "\n"; return 0; } ``` ---- ## for 迴圈 重複執行特定次數 ```txt for(初始值; 判斷式; 改變值) { 重複執行這段程式碼 } ``` ---- ## 用 for 迴圈輸出 1 ~ 10 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { for(int i = 1; i <= 10; i++) { cout << i << " "; } return 0; } ``` ---- ## 用 for 迴圈輸出 10 ~ 1 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { for(int i = 10; i > 0; i--) { cout << i << " "; } return 0; } ``` ---- ## 迴圈的控制 - continue - break ---- ## 請輸出 1 ~ 10, 但不要輸出 n 如果 n == 3 請輸出 ``` 1 2 4 5 6 7 8 9 10 ``` 如果 n == 8 請輸出 ``` 1 2 3 4 5 6 7 9 10 ``` 思考一下該怎麼做呢? ---- ## continue 跳過此次 繼續執行下一次 請輸出 1 ~ 10 但不要輸出 n ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; for(int i = 1; i <= 10; i++) { if(i == n) { continue; } cout << i << " "; } return 0; } ``` ---- ## break 結束迴圈 --- ## 陣列 Array 相同類型的元素所組成的資料結構 佔用連續區段的記憶體 ---- 如果我們要儲存三個數字 可以使用三個變數來存 ```cpp= int a,b,c; cin >> a >> b >> c; ``` ---- 那如果我們要儲存 100 個數字呢? 用 100 個變數來存? ```cpp= int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z; cin >> a >> b >> c >> d >> e >> f >> g >> h >> i >> j >> k >> l >> m >> n >> o >> p >> q >> r >> s >> t >> u >> v >> w >> x >> y >> z; ``` 顯然英文字母都不夠用了 而且超麻煩 ---- ## 宣告陣列 與宣告變數的方法相同 只是多了 陣列大小 ```cpp int a; // 宣告變數 ``` ```cpp int arr[5]; // 宣告陣列 ``` 示意圖 ![image](https://hackmd.io/_uploads/HkX-3fD4a.png) ---- ## 重要觀念 在 C++ 中 陣列 Array 的大小須事先宣告好 且為固定大小 若不知道要設多大 請仔細觀察題目給的數量範圍來決定 例如:有 $n$ 個數字 $1 \le n \le 1000$ 就可以把陣列大小開到 arr[1000] 以上 ---- ## 如果不想一開始就宣告大小呢? 可以使用 C++ STL 內建資料結構中的 vector 動態陣列 下學期社課會教 STL 中各種實用的資料結構 這節課先把陣列的基礎打好就好 ---- ## 初始化 初始化變數 ```cpp int a = 10; ``` 初始化陣列 ```cpp int arr[5] = {10,15,18,13,22}; ``` 初始化陣列(每項為 0) ```cpp int arr[5] = {0}; ``` ---- ## 索引值 index 元素在陣列中的位置 請記住 從 0 開始 ---- ## 陣列的讀取 ```cpp= #include <iostream> using namespace std; int main() { int arr[5] = {10,15,18,13,22}; cout << arr[1] << "\n"; return 0; } ``` 輸出結果: ||<font>15</font> || ---- ### 注意:不要讀取超過陣列大小的索引值 ```cpp= #include <iostream> using namespace std; int main() { int arr[5] = {10,15,18,13,22}; cout << arr[5] << "\n"; return 0; } ``` 會產生不預期的結果 請務必注意讀取範圍 ---- ## 陣列的修改 ```cpp= #include <iostream> using namespace std; int main() { int arr[5] = {10,15,18,13,22}; a[1] = 20; cout << arr[1] << "\n"; return 0; } ``` 輸出結果:||<font>20</font>|| --- ## 迴圈與陣列的結合 學完什麼是陣列以及陣列的索引值 還有讀取與修改陣列元素的方法 接著回到一開始的問題 我們該如何儲存大量的資料呢 或許我們不該宣告一大堆變數然後手動輸入 我們可以使用前面學的迴圈搭配剛學的陣列 來輸入並儲存大量資料 ---- 變數的輸入 ```cpp int a; cin >> a; ``` 陣列的輸入 ```cpp int a[5]; for(int i = 0; i < 5; i++) { cin >> a[i]; } ``` 可以發現我們利用迴圈讓 i 遞增 剛好就可以運用索引值來修改陣列中的每個元素 ---- 變數的輸出 ```cpp cout << a; ``` 陣列的輸出 ```cpp for(int i = 0; i < 5; i++) { cout << a[i]; } ``` 與輸入的概念相同 只是把迴圈中的 cin >> 變成 cout << 而已 ---- ## 陣列的排序 輸入 ```txt 3 6 5 8 10 1 4 2 7 9 ``` 輸出 ```txt 1 2 3 4 5 6 7 8 9 10 ``` ---- 對於陣列中雜亂無序的整數 可以使用內建函式 sort() 來排序裡面的元素 使用方法: sort(陣列名稱,陣列名稱 + 元素個數) ---- ## 程式碼 ```cpp= #include <iostream> using namespace std; int main() { int arr[10]; for(int i = 0; i < 10; i++) { cin >> arr[i]; } sort(arr, arr + 10); for(int i = 0; i < 10; i++) { cout << arr[i] << " "; } } ``` ---- ## 降序排序 sort()函式預設是由小排到大 如果要由大排到小 可以在函式中多加一個參數 ```cpp= // sort(陣列名稱, 陣列名稱 + 元素個數, 降序參數) sort(arr, arr + 10, greater<int>()); ``` ---- ## 排序演算法 初學者使用內建的排序函式就可以了 有興趣的人可以預習一下 [排序演算法 by ShiYu's Blog](https://4yu.dev/post/Sort-Algorithm/) 下學期有可能會教 --- ## 字串 String 由 <font color="yellow">連續字元</font> 所組成 以 " " 包起來 ---- ## 什麼是字串 ```cpp "" // 空字串 "abcdef" "ABCDEF" "123456" ``` 有用 " " 包起來的就是字串 ---- ## 如何宣告並初始化字串 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { string s0; // 宣告字串 預設為空字串 string s1 = "abcdef"; string s2 = "ABCDEF"; string s3 = "123456"; } ``` ---- ## 與陣列的相似之處 因為由連續的字元所組成 所以我們也可以用類似陣列的索引值 來存取字串中的單一字元 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { string s = "ABCDEF"; cout << s[0] << s[2] << "\n"; } ``` ## 輸出結果: ||<font>AC</font>|| ---- ## 字串的串接 可以使用 + 將兩個字串相接起來 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { string s1 = "ABC"; string s2 = "123"; cout << s1 + s2 << "\n"; } ``` ## 輸出結果: ||<font>ABC123</font>|| ---- ## 宣告空字串來玩文字接龍 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { string s; char c; while(cin >> c) { s += c; cout << s << "\n"; } } ``` - 輸入:N F I R C 輸出: ```txt= N NF NFI NFIR NFIRC ``` ---- ## 十進制轉二進制 ![image](https://hackmd.io/_uploads/HycgrhhB6.png) ---- ## 使用字串串接來完成二進制轉換 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n; string s; cin >> n; while(n != 0) { if(n % 2 == 1) s = "1" + s; else s = "0" + s; n /= 2; } cout << s << "\n"; } ``` ---- ## 讀取一整行字串 如何讀取一整行字串而不是每次只讀進一個單字呢? 我們可以使用 getline 函數 語法:getline(cin,s) ---- ## 使用 cin >> s ![image](https://hackmd.io/_uploads/SJelHj2Bp.png) ## 使用 getline(cin,s) ![image](https://hackmd.io/_uploads/SJDbSj2B6.png) ---- ### 如何計算字串的長度 要計算字串的長度 我們可以使用 size() 函數 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { string s; while(getline(cin,s)) { cout << s.size() << "\n"; } } ``` ![image](https://hackmd.io/_uploads/B1ogUo3ra.png) --- ## 延伸知識 - 各種字串的函數 - stringstream - 競程技巧:建表 ---- ## 各種字串的函數 - empty():判斷字串是否為空 - resize():改變字串長度 - substr():產生子字串 - find():尋找子字串 - to_string():數字轉字串 - stoi():字串轉數字 課堂上不細講 有興趣了解使用方法請看[這篇](https://www.mropengate.com/2015/07/cc-string-stl.html) ---- ## stringstream 用來處理特殊且複雜的輸入格式 [詳細使用方法文章](https://aprilyang.home.blog/2020/04/17/stringstream-to-read-int-from-a-string/) ---- ## 競程技巧:建表 輸入:4 1 8 1 8 8 如何統計每個數字各出現幾次呢? ---- ![image](https://hackmd.io/_uploads/rkI8qtTrp.png) ---- ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int a[10] = {0}; int n; while(cin >> n) { a[n]++; } for(int i=0;i<10;++i) { cout << a[i] << " "; } } ``` ![image](https://hackmd.io/_uploads/r1OBPcTBp.png) --- ## 必做題 [c726,c717,a034,a022,a466] 這次題單只有 5 題 但 5 題都是必做題 因為下一次社課的練習賽有一題是這 5 題的綜合版 ---- 題解待更新 --- ## 回饋表單 https://forms.gle/VLARSD79GCGLQU5z5 ![qr.ioi.tw (5)](https://hackmd.io/_uploads/HJPuHBarT.png)
{"title":"第 5 次社課講義","slideOptions":"{\"parallaxBackgroundImage\":\"https://hackmd.io/_uploads/Syfv9UoH6.png\",\"backgroundTransition\":\"none\",\"transition\":\"slide\",\"transitionSpeed\":\"slow\",\"controlsBackArrows\":\"faded\",\"spotlight\":{\"enabled\":false}}","description":"2023/12/06主講:ShiYu","contributors":"[{\"id\":\"a5e01884-520b-4df5-8e23-bfcc32fb4697\",\"add\":8877,\"del\":1198},{\"id\":\"133c1d63-1697-43cd-a9d9-860f755172d1\",\"add\":107,\"del\":8}]"}
    490 views
   owned this note