# 某人的期末 反正只是解題,下面四個變數就寫在全域吧,以後遇到這種問題的話,希望你已經學過struct跟malloc ## 版本一 ### Intro 學生數量: `int count;` 設計三個陣列來分別存 學生名字、學生成績、學生的編號(我們要自己紀錄的),這三個陣列裡面,同樣位置的資料會綁在一起: ``` char stud_name[30][51]; // 最多30個學生,不超過50個字長度的名字 int stud_score[30]; // 學生分數 int stud_order[30]; // 用來記錄最後輸出的時候學生的順序 // (Remi第一個出現,雖然分數第二名,還是要第一個輸出他) ``` 會用到的函數: ``` void Swap(int id0, int id1); // 同時交換 stud_name與stud_score 的 第id0跟id1 元素 void Sort(); // 只看分數來排序,然後用 swap 來改順序,這裡就用 bubble sort吧,把分數低的往後移 (分數最高就會是在stud_*[0]) void PrintAnswer(); // void main(); ``` 以範例輸入來說,最後會變成 ``` stud_name = ["Maria", "Remi", "Yan"] stud_score = [20, 14, 2] stud_order = [2, 0, 1] ``` 而我們要做的是,從stud_order來判斷,先輸出誰; 第一個要輸出 0 的學生(代表這個學生是當初的輸入的第一個),而在 stud_order[1] 找到 0,所以知道 stud_name[1] 是第 2 名 (index為1) ### 虛擬碼 #### `void Swap(int id0, int id1)` 1. (設變數) a. 生一個char array叫做 tmp_name (注意要夠大) b. 一個 int 叫做 tmp_score c. 一個 int 叫做 tmp_order 2. (這一步要把 id0 的學生先暫存起來) a. tmp_name = stud_name[id0] b. tmp_score = stud_score[id0] c. tmp_order = stud_order[id0] 3. (把 id0 的資料蓋掉,變成 id1) a. stud_name[id0] = stud_name[id1] b. stud_score[id0] = stud_score[id1] c. stud_order[id0] = stud_order[id1] 4. (把暫存起來,原本在 id0 的學生蓋到 id1 的位置) a. stud_name[id1] = tmp_name b. stud_score[id1] = tmp_score c. stud_order[id1] = tmp_order #### `void Sort();` 1. (設變數) ``` int end_id; int curr_id; ``` 2. 自己想想該怎麼sort吧 :::spoiler code ``` for (end_id = count; end_id >= 1; end_id--) { // keep on swappin for (curr_id = 1; curr_id < end_id; curr_id++) { if (stud_score[curr_id - 1] < stud_score[curr_id]) swap(curr_id - 1, curr_id); } } ``` ::: #### `void PrintAnswer();` ``` int target_order = 0; int pointer = 0; int i; for (i = 0; i < count; i++) { for (pointer = 0; pointer < count; pointer++) { if (stud_order[pointer] == target_order) { printf("%s rank is %d\n", stud_name[pointer], pointer+1); break; } } target_order++; } ``` #### `void main();` 1. 讀學生數到 count 2. 讀分數到 stud_score 3. 讀名字到 stud_name 4. 把 stud_order 填滿 0~count-1 (stud_order[0]=0, ..., stud_order[count-1] = count-1) 5. 呼叫 sort 6. 呼叫 print_answer