# 期末考總整理
沒有編譯器?這好用
{%preview https://www.onlinegdb.com/ %}
## 複習/技巧
### 1. ==左出右進== 這很重要
一堆人都會搞混,切記`cout <<`與`cin >>`!
然後要記得`std::`或`using namespace std;`。
### 2.加減乘除不能省,電腦很笨(但知道四則運算)
example:
```cpp=
int a = 5, b = 6;
cout << ab << endl;
```
~~~
error(電腦不知道ab是什麼變數!)
~~~
正解:
```cpp=
int a = 5, b = 6;
cout << a * b << endl;
```
~~~
30
~~~
### 3.清文沒教的實用東東:布林值
~~是說那個林O浩的邏輯不太好,充要必要還不會(笑)~~
跟`int`/`float`一樣是一種資料型態,但只有`true`跟`false`兩種可能,對應到數字就是非零為`true`零為`false`。再邏輯中條件回傳的就是布林。
example:
```cpp=
int a = 0;
if (a == 1) { // 回傳false
cout << "case1" << endl;
}
else {
cout << "case2" << endl;
}
```
~~~
case2
~~~
當然,也可以自己設
example:
```cpp=
bool a = true; // 也可以寫bool a = 1;
if (a == true) { //true,也可以簡寫為if(a)有同樣效果
cout << "case1" << endl;
}
else {
cout << "case2" << endl;
}
```
~~~
case1
~~~
### 4. = 與 ==
一個=是"指定",兩個=才是真正的"等於",你各位期中考多少人死在這自己自首!(笑
example:
```cpp=
int a = 0;
if (a = 1){ //1是true
cout << "case1" << endl;
}
else {
cout << "case2" << endl;
}
```
~~~
case1
~~~
因為a被指定成1了,非零者皆為真,所以才會變case1。
不過大於跟小於只有一個!! 兩個會變位元運算符(對,又一個清文沒說的東東)
ps那如果是大於等於跟小於等於呢?答案是`>=` `<=`。怕搞混也可以用`||`弄成等於或小於(大於)的形式。
### 5. `!` 的功能
`!`是做反轉功能,就是邏輯裡的"非",所以`!=`就是不等於,絕對跟階乘沒有關係,切勿排組做到走火入魔!
example:
```cpp=
int a = 5;
if (a == 0) {
cout << "case1" << endl;
}
if (a != 0) {
cout << "case2" << endl;
}
```
~~~
case2
~~~
### 6.`return 0;`的意義
這是函式的概念,反正記得在main裡面用的話會中止整個程式。
當然,保險起見有的話是最好。
### 7.一行程式的結尾`;`
C++不是看換行斷句是看分號! 除了預處理命令(`#`開頭)都要加。
## 期末考範圍:迴圈/陣列
### 迴圈
那個叫林什麼浩的不會迴圈是不是~ (這我可以笑三年)
### 1.`for`:可以重複執行子區域內的程式碼
```mermaid
graph TD
for-->初始式;
初始式-->判斷式;
判斷式-->False;
False---->迴圈下之程式;
判斷式-->True;
True-->陳述句;
陳述句-->遞增式;
遞增式-->判斷式;
```
直接看範例:
example:
```cpp=
int a = 5;
for (int i = 0; i < 5; i++) {
a++; // 就是a += 1;
}
cout << a << endl;
```
~~~
10
~~~
重複五次加一。
ps: 在for控制敘述內(括號內)才宣告的迴圈變數(通常是i) **有效區域只有那個for裡面!!**
這個概念之後有緣再來聊,反正如果想要保留i的話必須在for之外宣告。
example:
```cpp=
int a = 5;
int i;
for (i = 0; i < 5; i++) {
a++;
}
cout << i << endl;
```
~~~
5
~~~
但如果這樣就錯,因為找不到i。
```cpp=
int a = 5;
for (int i = 0; i < 5; i++) {
a++;
}
cout << i << endl;
```
~~~
error (電腦已經不認識i了)
~~~
### 2.`while`:只要條件符合就一直重複
```mermaid
graph TD
while --> 條件式
條件式 --> True
條件式 --> False
True --> 重複執行之程式
重複執行之程式 --> 條件式
False ---> 迴圈下之程式
```
一樣直接看範例:
example:
```cpp=
int a = 5;
while (a < 11) {
a++;
}
cout << a << endl;
```
~~~
11
~~~
也是重複五次加一,但是否停止取決於a自己。
example:
```cpp=
int a = 5;
while ( a > 11) {//進來時a是5,不合條件
a++;
}
cout << a << endl;
```
~~~
5
~~~
這個while就完全沒有進去。
如果你想搞點事
example:
```cpp=
int a = 5, bool b = true;
while (b) {//true
a++;
}
cout << a << endl;
```
```
(對,沒有輸出,因為沒有結束的時候)
```
可以直接寫:
```cpp=
int a = 5;
while (true) {
a++;
}
cout << a << endl;
```
### 3.`do-while`:先做再判斷
```mermaid
graph TD
do-->重複執行之程式;
重複執行之程式-->條件式;
條件式-->True;
條件式-->False;
True-->重複執行之程式;
False-->迴圈下之程式;
```
其實沒有很好用
example:
```cpp=
int a = 5;
do {
a++;
}
while (a > 11);
cout << a << endl;
```
~~~
6
~~~
理論上不該進這迴圈,但```do-while```強制讓他跑了一次
不過更建議複製貼上再執行while
example:
```cpp=
int a = 5;
a++;
while (a > 11) {
a++;
}
cout << a << endl;
```
~~~
6
~~~
### 4.`break`跟`continue`:跳脫指令
有點玄,`break`是直接跳出迴圈,`continue`則是跳進下一輪迴圈。
請看範例
example:
```cpp=
int a = 5;
while ( a < 11) {
a++;
if (a == 8) {
break;
}
}
cout << a << endl;
```
~~~
8
~~~
到8就跳出來了。
```cpp=
int a = 5;
while ( a < 11) {
a++;
if (a == 8) {
continue;
}
cout << a << endl;
}
```
~~~
6 7 9 10 11
~~~
到8時`cout`會被無視。
==切記,只跳脫"迴圈",即`for`跟`while`,`if`不是!==
## 陣列
### 1.陣列宣告
在宣告時用中括號表**長度(length)**,大括號表內容:
example:
```cpp=
int b[3];
int c[] = {1, 2, 3};
int d[5] = {1, 2, 3, 4, 5};
```
但切記,不可以既沒長度又沒內容(就像你各位的作文==)
example:
```cpp=
int a[];//這是違法的!!
```
因為電腦不知道要申請多少記憶體空間。
ps:當然,陣列也未必要是整數陣列,也可以```float a[5];```,
或```bool b[]={true,true,false}```之類。
### 2.陣列使用
在使用時,大括號內的數字是**索引值(index)**,20個人沒有第20號!!
example:
```cpp=
int c[] = {1, 2, 3};
cout << c[0] << " " << c[2] << endl;
```
~~~
1 3
~~~
所以以下是錯誤的
example:
```cpp=
int c[] = {1, 2, 3};
cout << c[3] << endl;
```
~~~
error (沒有3號!) // 會輸出奇怪數字
~~~
### 迴圈配陣列
這個應用必考!~~我感覺我好像對話式~~
比如說輸出陣列內容或輸入,都可以用```for```搞定
example:
```cpp=
int n = 5;
int c[n];
for (int i = 0; i < n; i++) {
c[i] = i;
}
for (int j = n - 1; j >= 0; j--) {
cout << c[j] << " ";
}
```
~~~
4 3 2 1 0
~~~
## 那些清文沒檢討的題目
供參考
### 輸出三角形
example:
1
```cpp=
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 5; i++) {
for (int j = 0; j < i; j++) {
cout << "*";
}
cout << endl;
}
}
```
~~~
*
**
***
****
*****
~~~
2
```cpp=
#include <iostream>
using namespace std;
int main() {
for (int i = 5; i > 0; i--) {
for (int j = 0; j < i; j++) {
cout << "*";
}
cout << endl;
}
}
```
~~~
*****
****
***
**
*
~~~
3
```cpp=
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 5; i++) {
for (int j = 1; j < i; j++) {
cout << " ";
}
for (int j = 0; j <= (5 - i); j++) {
cout << "*";
}
cout << endl;
}
}
```
~~~
*****
****
***
**
*
~~~
4
```cpp=
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 9; i += 2) {
for (int j = 0; j < (9 - i) / 2; j++) {
cout << " ";
}
for (int j = 0; j < i; j++) {
cout << "*";
}
cout << endl;
}
}
```
~~~
*
***
*****
*******
*********
~~~
### 猜數字
example:
```cpp=
#include <iostream>
using namespace std;
int main(){
int ans = 50;//任何數都可以
int counter = 0, input;
while (true) {
cout << "enter num:";
cin >> input;
counter++;
if (input < ans) {
cout << "too small" << endl;
}
else if (input > ans) {
cout << "too big" << endl;
}
else {
break;
}
}
cout<<"congratulation"<<endl<<"you tried "<<counter<< " times" << endl;
return 0;
}
```
~~~
enter num:70
too big
enter num:30
too big
enter num:50
congratulation
you tried 3 times
~~~
## 稍微進階的概念 ~~(偷吃步)~~
### algorithm裡的工具:sort
用來做排序,由小到大;
這我在期中考那份有用過,拿來找資料很方便,比如說那題找出最高分
期中考那份:
{%preview https://hackmd.io/KDvSjVGrRbiWKpHEhOZlgQ %}
平凡人的寫法
example:
```cpp=
#include <iostream>
using namespace std;
int main(){
int a[] = {3, 9, 2, 8, 1};
int max = 0;
for (int i = 0; i < 5; i++) {
if (max < a[i]) {
max = a[i];
}
}
cout << max << endl;
}
```
~~~
9
~~~
高手的寫法(經柏上身)
example:
```cpp=
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int a[5] = {3, 9, 2, 8, 1};
sort(a, a + 5);//排序範圍內的元素
cout << a[4];
}
```
~~~
9
~~~
因為整個陣列被我換成了`{1,2,3,8,9}`,所以我只要抓最後一個就好。
可能有人會問為啥是加五?不是沒有`a[5]`這一項?
這是因為機制是範圍為頭到尾但不包含尾(左閉右開),我只能說 先背吧。
### 隨機生成
可以讓電腦雖機丟數字給你,用剛剛那題猜數字來舉例
example:
```cpp=
#include <iostream>
#include <random>
#include <cstdlib>
using namespace std;
int main() {
srand (time (NULL));//先背...這不好解釋
int ans = (rand() % 100) + 1;//取亂數再限制範圍到1~100
int counter = 0, input;
while (true) {
cout << "enter num:";
cin >> input;
counter++;
if (input < ans) {
cout << "too small" << endl;
}
else if (input > ans){
cout << "too big" << endl;
}
else {
cout<<"error"<<endl;
return 0;
}
}
cout<<"congratulation"<<endl<<"you tried "<<counter<< " times" << endl;
}
```
其實這個亂數不是真正的亂數(偽隨機),但現在沒有很重要
## 練習題
有空可以來玩玩
### 1.(易)求總分平均
輸入五個整數,輸出總和與無條件捨去的平均值
```
10 20 30 40 50
```
```
150
30
```
### 2.(中)找最大與次大
第一格輸入是陣列大小n,之後n格輸入是陣列的每一個元素,求最大者與次大者。
```
6
20 50 10 40 30 45
```
```
50
45
```
### 3. (中)3N+1問題
輸入一整數,若為奇數則*3 + 1,偶數則 / 2,求出現的數形成之數列有幾項。
```
127
```
```
47
```
到這裡都應該還算期末考可能考的難度,再往下應該就不會了
### 4.(難)求孤單者
輸入9數(必然是一到五的整數),其中四個數出現兩次,輸出唯一只出現一次的數
```
3 1 4 5 3 1 4 2 2
```
```
5
```
### 5.(更難)進階求孤單者
同上題,但輸入數之範圍擴大至非負整數。
```
6 20 9 8 9 71 20 8 6
```
```
71
```
## 總結
期末考比起其中會更刺激更有趣,尤其是陣列配迴圈的操作一定考爛。電腦不會猜你意思,請務必搞清楚迴圈變數和陣列索引的關聯。
==一定要練,一定要練,一定要練,看得懂不等於寫得出,多打才是真的學會。==
加油:)
