程式設計實驗08 陣列與向量 -...

13
105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 1 程式設計實驗08 陣列與向量 研討問題05 5.1 使用call by value 和call by reference 進行函式呼叫有何差異? 請舉例說明,為何swap()函式必須 使用call by reference 可以有效地將傳入參數的內容互換;而call by value 則無法達成。 5.2 使用rand()函式來產生任意30 個亂數,並觀察其是否在每次主程式重新執行後亂數產生的順序都會一 樣? 若是,你會如何改善這個問題。 5.3 在課堂上老師已經講解了有關選擇排序(selection sort)的演算過程,並以微笑曲線代表對兩個陣列元 素進行比較後決定是否執行 swap 運算。假設排序的元素個數為 n, 則選擇排序的微笑曲線數為 n(n-1)/2,亦即進行比較的次數為 n(n-1)/2。已知 time()函式可以取得系統時間, 你要如何利用 time() 函式來統計當 n 分別為 100、200、300 時,電腦執行選擇排序所花費的時間關係。 程式設計實驗8.1:使用亂數產生器模擬擲同時兩個骰子。 提示 1:使用 MIT App Inventor 設計,參考以下 UI 設計及 Blocks MIT App Inventor 網址:http://ai2.appinventor.mit.edu/

Transcript of 程式設計實驗08 陣列與向量 -...

Page 1: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 1

程式設計實驗08 陣列與向量

研討問題05

5.1 使用call by value 和call by reference 進行函式呼叫有何差異? 請舉例說明,為何swap()函式必須

使用call by reference 可以有效地將傳入參數的內容互換;而call by value 則無法達成。

5.2 使用rand()函式來產生任意30 個亂數,並觀察其是否在每次主程式重新執行後亂數產生的順序都會一

樣? 若是,你會如何改善這個問題。

5.3 在課堂上老師已經講解了有關選擇排序(selection sort)的演算過程,並以微笑曲線代表對兩個陣列元

素進行比較後決定是否執行 swap 運算。假設排序的元素個數為 n, 則選擇排序的微笑曲線數為

n(n-1)/2,亦即進行比較的次數為n(n-1)/2。已知 time()函式可以取得系統時間, 你要如何利用 time()

函式來統計當 n分別為 100、200、300 時,電腦執行選擇排序所花費的時間關係。

程式設計實驗8.1:使用亂數產生器模擬擲同時兩個骰子。

提示 1:使用MIT App Inventor 設計,參考以下 UI 設計及 Blocks

MIT App Inventor 網址:http://ai2.appinventor.mit.edu/

Page 2: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 2

提示 2:使用 Dev C++設計,參考以下 C++程式碼及輸出畫面

// dice.cpp

#include <ctime>

#include <iostream>

using namespace std;

int main()

{

int dice1, dice2;

srand(time(0));

dice1=1 + rand()%6;

dice2=1 + rand()%6;

cout<<dice1<<" "<<dice2<<endl;

system("pause"); return 0;

}

提示 3:使用#develop設計

SharpDevelop 5下載網址:http://www.icsharpcode.net/OpenSource/SD/Download/

程式設計實驗8.2:使用亂數產生器模擬同時擲兩個骰子100萬次,並統計點數和為2、3、…、以及12出

現的機率。

提示:參考以下 C++程式碼及輸出畫面

// dice_statistic.cpp

#include <iostream>

#include <ctime>

#include <cstdlib>

using namespace std;

int main()

{

int dice1, dice2;

int fq[13]={0};

srand(time(0));

Page 3: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 3

for (int i=0; i<1000000; i++){

dice1=1 + rand()%6;

dice2=1 + rand()%6;

fq[dice1+dice2]++;

}

for (int i=2;i<13;i++)

cout<<i<<": "<<fq[i]/1000000.0<<endl;

system("pause");

return 0;

}

程式設計實驗8.3:使用選擇排序法,自行定義一個可以將一維整數陣列的元素從小排到大的函式。

提示:參考以下 C++程式碼及輸出畫面

// selection_sort.cpp #include <cstdlib> #include <iostream> using namespace std; void selection_sort(int x[], int n) { for (int i=0; i<n; i++) for (int j=i+1; j<n; j++) if (x[i]>x[j]) swap(x[i], x[j]); } int main() { int A[]={7, 35, 40, 19, 13}; for (int i=0;i<5;i++) cout<<A[i]<< " "; cout<<endl; selection_sort(A, 5); cout<<"After calling selection_sort(A, 5):\n"; for (int i=0;i<5;i++) cout<<A[i]<< " "; cout<<endl; system("pause"); return 0; }

程式設計實驗8.4:使用泡沫排序法,自行定義一個可以將一維整數陣列的元素從大排到小的函式。

提示:參考以下 C++程式碼及輸出畫面

// bubble_sort.cpp

#include <cstdlib>

#include <iostream>

using namespace std;

void bubble_sort (int x[ ], int n)

{

for (int i=0;i<n-1;i++)

for (int j=0;j<n-1-i;j++)

if (x[ j+1]<x[j]) swap(x[j], x[ j+1]);

}

int main()

{

int A[]={7, 35, 40, 19, 13};

for (int i=0;i<5;i++) cout<<A[i]<< " ";

cout<<endl;

Page 4: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 4

bubble_sort(A, 5);

cout<<"After calling bubble_sort(A, 5):\n";

for (int i=0;i<5;i++) cout<<A[i]<< " ";

cout<<endl;

system("pause");

return 0;

}

程式設計實驗8.5:自行定義一個可以將nn矩陣加以轉置的函式。

提示:參考以下 C++程式碼及輸出畫面

// transpose.cpp

#include <iostream>

using namespace std;

void transpose(int x[][3], int n)

{

for (int i=0;i<n;i++)

for (int j=i+1;j<n;j++) swap(x[i][j], x[j][i]);

}

int main()

{

int A[][3]={ {1,1,1}, {0,1,1}, {0,0,1} };

for (int i=0;i<3;i++) {

for (int j=0;j<3;j++) cout<<A[i][j]<< " ";

cout<<endl;

}

transpose(A, 3);

cout<<"After calling transpose(A, 3):\n";

for (int i=0;i<3;i++) {

for (int j=0;j<3;j++) cout<<A[i][j]<< " ";

cout<<endl;

}

system("pause"); return 0;

}

程式設計實驗8.6:使用vector向量物件,重新定義程式設計實驗8.4的泡沫排序函式。

提示:參考以下 C++程式碼及輸出畫面

// vector.cpp

#include <vector>

#include <iostream>

using namespace std;

void bubbleSort(vector<int>& x)

{

for (int i=0; i < x.size()-1; i++)

for (int j=0; j < x.size()-1-i; j++)

if ( x[j+1] < x[j] ) swap(x[j], x[j+1]);

}

int main()

{

vector<int> x(5);

for(int i=0; i<x.size(); i++) cin>>x[i];

bubbleSort(x);

for(int i=0; i<x.size(); i++) cout<<x[i]<< " ";

cout<<endl;

Page 5: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 5

system("pause");

return 0;

}

程式設計實驗8.7:讀取實驗06產生的成績檔,載入成績物件後,應用C++ Vector物件或C#陣列

物件加以排序,並顯示排名及成績分布情形。

提示 1:使用 Dev C++設計,參考以下 C++程式碼及輸出畫面

#include <iostream> #include <iomanip> using namespace std; #include <fstream> #include <vector> //… class Score { public: char name[9]; int programming; int economics; int mis; double average; int rank; }; //… void swap(Score &x, Score &y) { Score tmp=x; x=y; y=tmp; } //… void selectionSort(vector<Score> &, int, bool); //… void bubbleSort(vector<Score> &, int, bool); // … int main() { int dist[10]={0}; //…. vector<Score> grade(50); //… double max=0, min=100; //… ifstream fin("grade.csv", ios::in); //… if (!fin) cout<<"檔案開啟失敗"<<endl; else { char sentence[81]; fin.getline(sentence, 81, '\n'); //… double sum=0; //… int n=0; //… do{ fin.getline(grade[n].name,9,','); //… fin>>grade[n].programming; fin.get(); //… fin>>grade[n].economics; fin.get(); //… fin>>grade[n].mis; //… //… grade[n].average=(grade[n].programming+grade[n].economics+grade[n].mis)/3.0; if (grade[n].average>max) max = grade[n].average;

Page 6: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 6

if (grade[n].average<min) min = grade[n].average; //… sum+=grade[n].average; if (grade[n].average>=90) dist[9]++; else if (grade[n].average>=80) dist[8]++; else if (grade[n].average>=70) dist[7]++; else if (grade[n].average>=60) dist[6]++; else if (grade[n].average>=50) dist[5]++; else if (grade[n].average>=40) dist[4]++; else if (grade[n].average>=30) dist[3]++; else if (grade[n].average>=20) dist[2]++; else if (grade[n].average>=10) dist[1]++; else if (grade[n].average>=0) dist[0]++; n++; }while(fin.get()!=EOF); //… fin.close(); //…

//… cout<<endl<<endl;

cout<<"N: "<<n<<endl; cout<<"Avg: "<<fixed<<setprecision(2)<<(sum/n)<<endl; cout<<"Max: "<<max<<" "<<"Min: "<<min<<endl; cout<<endl<<"-------------------"<<endl; for (int i=9;i>=0;i-=1) cout<<i*10<<"-"<<(i*10+9)<<": "<<dist[i]<<endl; cout<<"-------------------"<<endl; for (int i=0;i<n;i++) cout<<grade[i].name<<" "<<grade[i].programming<<" " <<grade[i].economics<<" "<<grade[i].mis<<endl; cout<<endl; //… selectionSort(grade, 2, false);

//… int k=1; grade[0].rank=k; for (int i=1;i<n;i++){ if (grade[i].average < grade[i-1].average) k=i+1; grade[i].rank=k; } bubbleSort(grade, 1, true); //…

//… char *strptr; strptr=strtok(sentence,","); while(strptr!=NULL){ cout<<" "<<strptr; strptr=strtok(NULL,","); } cout<<" 總平均 名次\n"

<<"---------------------------------------------------------"<<endl; //… for (int i=0;i<n;i++) cout<<grade[i].name<<" "<<grade[i].programming<<" " <<grade[i].economics<<" "<<grade[i].mis <<" "<<fixed<<setprecision(2)<<grade[i].average <<" "<<grade[i].rank<<endl; cout<<"---------------------------------------------------------"<<endl;

Page 7: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 7

} system("pause"); return 0; } //… void selectionSort(vector<Score> &x, int field, bool ascending) { cout<<"selectionSort()..."<<endl; for (int i=0;i<x.size()-1;i++) for (int j=i+1;j<x.size();j++) switch(field){ case 1: if (ascending){ if (strcmp(x[i].name, x[ j].name)>0) swap(x[i], x[ j]); } else { if (strcmp(x[i].name, x[ j].name)<0) swap(x[i], x[ j]); } break; case 2: if (ascending){ if (x[i].average > x[ j].average) swap(x[i], x[ j]); } else { if (x[i].average < x[ j].average) swap(x[i], x[ j]); } break; } } //… void bubbleSort(vector<Score> &x, int field, bool ascending) { cout<<"bubbleSort()..."<<endl; for (int i=0;i<x.size()-1;i++) for (int j=0;j<x.size()-i-1;j++) switch(field){ case 1: if (ascending){ if (strcmp(x[ j].name, x[ j+1].name)>0) swap(x[ j], x[ j+1]); } else { if (strcmp(x[ j].name, x[ j+1].name)<0) swap(x[ j], x[ j+1]); } break; case 2: if (ascending){ if (x[ j].average > x[ j+1].average) swap(x[ j], x[ j+1]); } else { if (x[ j].average < x[ j+1].average) swap(x[ j], x[ j+1]); } break; } }

使用 Dev-C++進行編譯執行後,觀察結果:

Page 8: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 8

創作指引:本模擬問題基礎程式尚未提供個人成績查詢功能,請規劃並分析如何增加個人成績查詢功

能?

提示 2:使用#develop設計,參考以下 UI 設計、C#程式碼、及輸出畫面

SharpDevelop 5 下載網址:http://www.icsharpcode.net/OpenSource/SD/Download/

應用 C#陣列物件加以排序,並利用視窗元件顯示排名及成績分布情形

建立 C# Windows Application 專案:GradeManagement

新增 Score 類別:Score.cs

// 自行定義 Score 類別:Score.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GradeManagement { class Score { //... public static string title_id { set; get; } public static string title_name { set; get; } public static string title_computer { set; get; } public static string title_programming { set; get; } public static string title_accounting { set; get; } public static string title_economics { set; get; } public static string title_calculus { set; get; } public static string title_average { set; get; } public static string title_rank { set; get; }

Page 9: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 9

//... public string id { set; get; } //... public string name { set; get; } //... public int computer { set; get; } //... public int programming { set; get; } //... public int accounting { set; get; } //... public int economics { set; get; } //... public int calculus { set; get; } //... public double average { set; get; } //... public int rank { set; get; } //... //... public Score(string aId, string aName, int aComputer, int aProgramming, int aAccounting,

int aEconomics, int aCalculus){ id = aId; name = aName; computer = aComputer; programming = aProgramming; accounting = aAccounting; economics = aEconomics; calculus = aCalculus; average = (aComputer + aProgramming + aAccounting + aEconomics + aCalculus) / 5.0; rank = -1; } } }

設計主表單 Form1 類別:Form1.cs(SharpDevelop 預設名稱為 MainForm)

// C#表單類別:Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace GradeManagement { public partial class Form1 : Form { //... public Form1() { InitializeComponent(); } //... private StreamReader reader; //... private Score[] grade = new Score[50]; //... private void showTitle() { textBox2.Clear(); //... string title = String.Format("{0,-14} {1,-8} {2,-2} {3,-2} {4,-2} {5,-3} {6,-3} {7,-3} {8,-2}\n", Score.title_id, Score.title_name, Score.title_computer,

Score.title_programming, Score.title_accounting, Score.title_economics, Score.title_calculus, Score.title_average, Score.title_rank);

textBox2.Text += title + Environment.NewLine; } //... private void button1_Click(object sender, EventArgs e)

Page 10: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 10

{ try { //... reader = new StreamReader(File.OpenRead(textBox1.Text), Encoding.Default);

//顯示中文Encoding.Default //... textBox2.Clear(); //... string line = reader.ReadLine(); char[] seps = {','}; string[] lineTokens = line.Split(seps); //... textBox2.Text += line + Environment.NewLine; //... Score.title_id = lineTokens[0]; Score.title_name = lineTokens[1]; Score.title_computer = lineTokens[2]; Score.title_programming = lineTokens[3]; Score.title_accounting = lineTokens[4]; Score.title_economics = lineTokens[5]; Score.title_calculus = lineTokens[6]; Score.title_average = "平均"; Score.title_rank = "排名"; //... int n=0; while(!reader.EndOfStream) { line = reader.ReadLine(); textBox2.Text += line + Environment.NewLine; lineTokens = line.Split(seps); //... grade[n] = new Score( lineTokens[0], lineTokens[1], Int32.Parse(lineTokens[2]), //... Int32.Parse(lineTokens[3]), Int32.Parse(lineTokens[4]), Int32.Parse(lineTokens[5]), Int32.Parse(lineTokens[6])); n++; } reader.Close(); //... } catch (Exception ee) { textBox2.Text = ee.ToString(); } //... } //... private void button2_Click(object sender, EventArgs e) { if (reader == null) { textBox2.Text = "請先讀取成績檔案"; } else { //... showTitle(); //... for (int i = 0; i < grade.Length; i++) { //... string line = String.Format(

"{0,-8} {1,-6} {2:###} {3:###} {4:###} {5:###} {6:###} {7:###.0}", grade[i].id, grade[i].name, grade[i].computer, grade[i].programming, grade[i].accounting, grade[i].economics, grade[i].calculus,

grade[i].average); textBox2.Text += line + Environment.NewLine; } }

Page 11: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 11

} //... private void button3_Click(object sender, EventArgs e) { if (reader == null) { textBox2.Text = "請先讀取成績檔案"; } else { //... Array.Sort(grade, delegate(Score score1, Score score2) { // 由大排到小 (score2.average - score1.average) return score2.average.CompareTo(score1.average); }); //... int k = 1; grade[0].rank = k; for (int i = 1; i < grade.Length; i++) { if (grade[i].average < grade[i - 1].average) k = i + 1; grade[i].rank = k; } //... Array.Sort(grade, delegate(Score score1, Score score2) { return score1.id.CompareTo(score2.id); // 由小排到大 (score1.id - score2.id) }); //... showTitle(); //... for (int i = 0; i < grade.Length; i++) { //... string line = String.Format( "{0,-8} {1,-6} {2:###} {3:###} {4:###} {5:###} {6:###} {7:###.0} {8:###}", grade[i].id, grade[i].name, grade[i].computer, grade[i].programming, grade[i].accounting, grade[i].economics, grade[i].calculus, grade[i].average, grade[i].rank); textBox2.Text += line + Environment.NewLine; } } } //... private void button4_Click(object sender, EventArgs e) { if (reader == null) { textBox2.Text = "請先讀取成績檔案"; } else { double max = 0, min = 100; double sum = 0, average = 0; int[] dist = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (int i = 0; i < grade.Length; i++) { if (grade[i].average > max) max = grade[i].average; if (grade[i].average < min) min = grade[i].average; sum += grade[i].average; if (grade[i].average >= 90) dist[9]++; else if (grade[i].average >= 80) dist[8]++; else if (grade[i].average >= 70) dist[7]++; else if (grade[i].average >= 60) dist[6]++; else if (grade[i].average >= 50) dist[5]++; } average = sum / grade.Length; textBox2.Clear(); textBox2.Text += "班級平均:" + average + Environment.NewLine; textBox2.Text += "最高分:" + max + Environment.NewLine; textBox2.Text += "最低分:" + min + Environment.NewLine;

Page 12: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 12

for (int i = 9; i >= 0; i -= 1) textBox2.Text += i * 10 + "-" + (i * 10 + 9) + ": " + dist[i] + Environment.NewLine; } } private void timer1_Tick(object sender, EventArgs e) { label2.Text = DateTime.Now.ToString(); } private void Form1_Load(object sender, EventArgs e) { timer1.Enabled = true; } } }

觀察主程式 Program 類別:Program.cs

// C#主程式類別:Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace GradeManagement { static class Program { /// <summary> /// 應用程式的主要進入點。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); //… Application.SetCompatibleTextRenderingDefault(false); //… Application.Run(new Form1()); //… } } }

使用 Visual Studio 2012 或 Sharp Develop 進行編譯執行後,觀察結果:

Page 13: 程式設計實驗08 陣列與向量 - eclass.nttu.edu.tweclass.nttu.edu.tw/sysdata/doc/9/9d6352426cf58b36/pdf.pdf · 105A 資管一 程式設計實驗08 陣列與向量 謝明哲老師

105A 資管一 程式設計實驗 08 陣列與向量 謝明哲老師 [email protected] 13

創作指引:

本模擬問題基礎程式尚未提供個人成績查詢功能,請規劃並分析如何增加個人成績查詢功能。

使用工具箱提供的 OpenFileDialog 元件提高成績檔案名稱輸入的使用性。

使用工具箱提供的 ReportViewer 元件顯示成績分布統計圖。