--- tags: 文華社課 --- > 文華高中電腦研究社29th > 編輯 : 黃昱凱 > 宣傳 : 平時練C++ㄉ小號 https://www.instagram.com/l.o.l.i.c.o.n._learning_cpp/ # C++從零入門 Level 1-2 接著就是也粉重要的迴圈~~ 迴圈就是當我們想要把一段程式做好幾次的時候使用 假設有個題目要求 1.輸出1次 hi 並換行 這個你會,就輸出嘛~ ```cpp= #include<iostream> using namespace std; int main(){ cout <<"hi"<<endl; //記得字串用雙引號 return 0; } ``` 2.輸出100次 hi 並換行 沒有迴圈會發生恐怖的事 要寫100行 ```cpp= #include<iostream> using namespace std; int main(){ cout <<"hi"<<endl; cout <<"hi"<<endl; cout <<"hi"<<endl; cout <<"hi"<<endl; cout <<"hi"<<endl; ......以下省略95行 return 0; } ``` 所以,做多次運算會需要迴圈~ ## 迴圈 大概就兩種~ ### for迴圈 語法如下(公式取向) ```cpp for(int i = 0;i < 你想做的次數;i ++){ 程式 } ``` 範例如下: ```cpp for(int i = 0;i < 5;i ++){ cout << "hi" <<endl; } ``` :::success 結果: ~~~ hi hi hi hi hi ~~~ 執行五次 ::: 要注意的是,程式都是**從零開始跑的** 也就是說,以剛剛的例子改成輸出 i ```cpp for(int i = 0;i < 5;i ++){ cout << i <<endl; } ``` :::success 結果: ~~~ 0 1 2 3 4 ~~~ 一樣執行五次,i = 0, 1, 2, 3, 4; ::: 也就是說上述for迴圈中 i 由 **<font color = #8a2be2>0 跑到 n-1 , 共n次** </font> 也因此這種迴圈也稱 <font color = #8a2be2> **計次型迴圈** </font> 這裡講更精確一點 for迴圈語法(非公式取向) ```cpp for( [A.]一開始先做什麼事 ; [B.]條件式 ; [D.]等C每作完一次,就做什麼事 ) { [C.]當B條件成立時,就重覆做的事... } ``` 通常A、B、D所用到的變數會是一致的。 執行起來流程如下 先做A ==> 檢查B條件,成立就做C,接著做D ==> 檢查B條件,成立就做C,接著做D ==> 檢查B條件,成立就做C,接著做D ... ... ==> 檢查B條件,成立就做C,接著做D ==> 檢查B條件,不成立離開 (from 黃佑仁_C++與演算法) #### 範例,請依序輸出數字100至0,數字間用空格分開: 根據此題的條件,設變數為i [A.]一開始先做什麼事: 最開始設定i為100 [B.]條件式: 當i仍然大於等於0時,繼續跑迴圈 [C.]當B條件成立時,就重覆做的事: 輸出現在的i值和一個空格 [D.]等C每作完一次,就做什麼事: 每跑完一次迴圈,i減1 程式如下 ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ for(int i = 100;i >= 0;i --){ cout << i << " "; } } ``` :::success 結果: ~~~ 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ~~~ 迴圈執行101次(等於0時也執行) ::: #### 偶數? 同個道理 請輸出依序**100到1**的每個偶數,數字間以空白分開 一樣根據此題的條件,設變數為i [A.]一開始先做什麼事: 最開始設定i為100 [B.]條件式: 當i仍然**大於0**時,繼續跑迴圈 [C.]當B條件成立時,就重覆做的事: 輸出現在的i值和一個空格 [D.]等C每作完一次,就做什麼事: 每跑完一次迴圈,**i減2** (效果:100, 100-2, 100-4....) 範例程式: ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ for(int i = 100;i > 0;i -= 2){ cout << i << " "; } } ``` :::success 結果: ~~~ 100 98 96 94 92 90 88 86 84 82 80 78 76 74 72 70 68 66 64 62 60 58 56 54 52 50 48 46 44 42 40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2 ~~~ 迴圈執行50次(等於0時**不**執行) ::: ### while迴圈 這個就簡單很多 語法如下 ```cpp while(條件){ 程式 } ``` 如果<font color = #8a2be2>**條件達成-> 不斷執行程式,直到條件不達成** </font> 範例1: ``` int a = 5; while(a > 0){ a--; // a -= 1 cout << a << endl; } ``` :::success 結果: ~~~ 5 4 3 2 1 ~~~ ::: #### 哈哈又是偶數? 同個道理 請輸出依序**100到1**的每個偶數,數字間以空白分開 一樣根據此題的條件,設變數為i 當 i 大於 0 時一直執行 "輸出後減2",直到 i 不大於 0 範例程式: ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ int i = 100; while(i > 0){ // 當i = 0時,不會進行輸出 cout << i <<" "; i -= 2; } } ``` :::success 結果: ~~~ 100 98 96 94 92 90 88 86 84 82 80 78 76 74 72 70 68 66 64 62 60 58 56 54 52 50 48 46 44 42 40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2 ~~~ 迴圈執行50次(等於0時**不**執行) ::: 原則上,for 和 while都可以互換使用 可以視情況調整 另外 ### 多筆測資與EOF 檔案結尾(英語:End of File,縮寫為EOF) 可以判定本筆測資的結束 如果題目要求多筆測資 可以用while(cin >> x)處理 範例: ```cpp= int k; while(cin >> k){ cout << k * 2 <<endl; } ``` 效果:處裡多筆資料 :::success 輸入: ~~~ 5 4 7 1 0 ~~~ 結果: ~~~ 10 8 14 2 0 ~~~ ::: 這樣一來很多上章不會的題目都可解了~~ :::success - [ ] [例題:a058: MOD3](https://zerojudge.tw/ShowProblem?problemid=a058) 第一行就告訴你要做幾次了喔~ 用計次型for比較方便 先備知識: * if-else結構 ::: :::success - [ ] [e156: 良心題: 求和](https://zerojudge.tw/ShowProblem?problemid=e156) 先不要管什麼是良心w 就先用迴圈寫看看 ::: =-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ### 陣列 其實我不知道10月toi練習賽有沒有陣列w 先講一點起來,因為陣列的應用範圍可大了 陣列可以幫助我們儲存大量資料 大概長這樣 ![](https://i.imgur.com/pGWsDKw.jpg) ... 喔不對,這是陳列w 下面的才是陣列 ![](https://i.imgur.com/wQe9nOE.png) 基本上,陣列的每個空間都有它的索引值(index) 如果宣告一個空間為N的陣列 **index就是0 ~ N-1** #### 宣告方式 ```cpp int a[N]; // 使用中刮號,N為陣列大小,整數型別陣列 int b[N] = {idx_0, idx_1, idx_2......., idx_N-1}//使用大刮號直接定陣列內容 // 其他例 char c[7] = {'l', 'o', 'l', 'i', 'c', 'o', 'n'}; // 實例 int a[5]; int b[3] = {1, 3, 5};//此陣列有三項,第0項 = 1, 第1項 = 3, 第2項 = 5 ``` #### 儲存及修改方式 ```cpp int a[5]; // 先宣告 a[0] = 1; a[1] = 3; a[2] = 5; a[3] = 7; a[4] = 9; // 輸出看看 for(int i = 0;i < 5;i ++){ cout << a[i] <<" "; } ``` :::success 輸出: ~~~ 1 3 5 7 9 ~~~ ::: 不只int可以開陣列 其他資料型別也可以 ```cpp char a[N]; bool b[N]; float c[N]; double d[N]; ...... ``` 另外值得一提的是 string 本身就是一個 char型別的陣列(更正:不完全是,char結尾需是null) 可以被搜尋或修改 範例: ```cpp string s = "lolicon_"; s[3] = 'l';//字元用單引號 s[4] = 'i'; s[5] = 'p'; s[6] = 'o'; s[7] = 'p'; cout << s <<endl; ``` :::success 結果: ~~~ lollipop ~~~ ::: :::warning - [ ] [例題a038: 數字翻轉](https://zerojudge.tw/ShowProblem?problemid=a038) 比較複雜,可以瞄一下解答或聽課~ 強制轉型string 到 int 用 stoi() continue 跳過 ::: :::warning - [ ] [進階題:a693 吞食天地](https://zerojudge.tw/ShowProblem?problemid=a693) 這題先測試執行通過就好 因為目前學的會TLE(超時) 如果真的想過 先備知識: * 前綴和 ::: :::danger - [ ] [進階題:a693 吞食天地](https://zerojudge.tw/ShowProblem?problemid=a693) 如果你直接過了,那真的就很猛了w 先備知識 * 前綴和(prefix sum) * 差分陣列 ::: ::: 如果寫不過癮可以試試下面的類題(沒有答案~~) :::danger - [ ] [a015: 矩陣的翻轉](https://zerojudge.tw/ShowProblem?problemid=a015) ::: ::: info 此處為本次社課結束點 有問題都殼以找窩或傳訊息問喔~ 物理和數學悲劇的 蘿莉控 副社_黃昱凱 敬上 ::: > 下一章: [C++從零入門 Level 2](https://hackmd.io/@lolicon5208/rypUUGaOK) > 目錄: [C++從零入門](/G0dWqZR7RIOwrK6gK0tEZg) ## 參考解答 先想想再偷看喔w ### a058: ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ int n; cin >> n; int mod3_0 = 0, mod3_1 = 0, mod3_2 = 0; for(int i = 0;i < n;i ++){//做n次 int k; cin >> k; if (k % 3 == 0){ mod3_0++;//mod3_0 = mod3_0 + 1; } if (k % 3 == 1){ mod3_1++; } if (k % 3 == 2){ mod3_2++; } } cout << mod3_0 <<" "<< mod3_1 <<" "<< mod3_2 <<endl; return 0; } ``` ### e156: ```cpp= #include<iostream> using namespace std; int main(){ int n; cin >> n; int total = 0; for(int i = 1;i <= n;i ++){ total += i; } cout << total <<endl; return 0; } ``` ### a038: ```cpp= #include<iostream> using namespace std; int main(){ string s; char a[10000]; cin >> s; int l = s.length(); bool test = 1; if (stoi(s) == 0){ //強制轉型 cout << 0 <<endl; return 0; } for(int i = 0;i < l;i ++){ a[i] = s[l-i-1]; if (a[i] != '0'){ test = 0; } if (a[i] == '0' && test == 1){ continue;//跳過本次執行 } cout << a[i]; } return 0; } ``` ### a693: TLE code: ```cpp= #include<iostream> using namespace std; int main(){ int m, n; int a[100005]; while(cin >> m >> n){ for(int i = 1;i <= n;i ++){ cin >> a[i]; } int l, r; while(cin >> l >> r){ int total = 0; for(int i = l;i <= r;i ++){ total += a[i]; } cout << total <<endl; } return 0; } } ``` 真的想不出來怎麼解難題請往這邊~ link:https://hackmd.io/@lolicon5208/BJuU4_bIF