LAB-11 從檔案讀入資料並排序後印出部份資料 Due: 這題分三個階段 Due: (1)只寫研讀題目與相關範例的心得, Due 一週內! Due 後才交打五折!! 以下算做 Lab-12, Lab-13; Due 過後繳交則分數逐週打九折! (2)Lab-12: 不可用struct, 即日起兩週內 (第三週仍可繳交, 但分數打九折) (3)Lab-13: 必須用struct做, Due : 比不使用 struct 的版本多一週 :-) Purpose: (1)學習如何把資料按照某種順序 Sort (排序). 順便學習如何寫入檔案與讀取檔案. (2)並從程式庫中的 qsort( ) 用法學習 call back function; (請用 gogle.com 查詢 "call back function" ) (3)也學習使用 資料結構的基本 struct 來組織資料, 以及站在巨人的肩膀上: 使用 C++ 的 STL 程式庫中的 sort; ** 常見排序法: Selection sort, Insertion sort, Bubble sort, Quick sort 說明: 寫一個程式可以: 從檔案 studat.txt 讀入一堆學生資料, 然後依照規定排序並輸出! 在 studat.txt 裡面每列為一位學生資料, 有學號, 姓名, 作業成績 h, 期中考成績 m, 小考成績 q, 期末考成績 f, 你要: (1)讀入資料並先算出每人的學期總成績 : 學期總成績 = (h*0.2 + m*0.3 + q*0.1+f*0.4); (此項印到小數點後兩位) 然後印出 學號, 姓名, 接著各次成績, 以及學期總成績 (以學號為序) 印完學生資料後, (因資料很多, 只印出前面6個, 以及最後面6個) 必須再印出全部同學的 學期總成績之平均, 以及總成績的標準差; (2)把資料排序, 怎麼做自己決定, 但必須量測sorting時間, 且還要印出: 照學期總成績由高排到低的前面6個, 以及最後面6個(學期總成績最低的)的資料! (3)再來, 印出照學號由小到大排序的前面6個, 以及最後面6個的資料! (extra credit: 每列最右邊多印名次) 請注意: 這題分三個階段繳交: (1)寫出這題的題目與相關範例的研究心得, 至少500字! 至多 1200字! (2)不可使用 struct 結構完成這習題, 練習時間是這週和下週共兩週。 (3)必須使用 struct 結構完成這習題, 練習時間是下週和下下週, 也是共兩週! Hint: (1) 資料請用作業區所給的 genscore.c 產生, (也研究該程式 :-) 讀取資料請參考 readtest.c (當然也要研究該程式 :-) 關於 sorting 請參看所給的其他四個 sorting 範例: bbsort.c, selsort.c, inssort.c, 和 myqsort.cpp (2) 習題程式請用所給的 hwk11.c 改寫 (可用C或C++); ^^^^^^^^^^^^^^^^^^^^^^^^^ (3) 要使用何種 sorting 技巧隨你高興, 但都須量測出你 sorting 所花的時間。 ** 關於 Sorting 方法, 除看範例外, 也可用 wikipedia 找各種 sorting, 例如 bubble sort, Insertion sort, Selection sort 等! http://en.wikipedia.org/wiki/Bubble_sort http://en.wikipedia.org/wiki/Insertion_sort http://en.wikipedia.org/wiki/Selection_sort 除了產生資料的 genscore.c 和 讀取資料範例 readtest.c, 以及這習題雛形 hwk1213.c 外, 也請參考所給的 .. 範例 bbsort.c, selsort.c, inssort.c, 以及 myqsort.cpp (C++程式) ***以上所有程式, 以及本檔案, 也可以在備用網站找到: http://www.cs.nctu.edu.tw/~tsaiwn/introcs/03_Labs/Lab11/ *** 一週後會公佈使用 struct 搭配 程式庫函數 qsort( ) 的參考答案 *** 三週後會公佈沒有用 struct, 且自己寫 sort 函數之參考答案 *** 四週後會公佈使用 struct 搭配 C++ STL 的 sort 之參考答案 __________________________________________________________ 以下是由 genscore.c 生出之 studat.txt 的前面 3 lines 9938596 章LUf 76 74 79 98 9934067 趙NLv 72 64 61 94 9947865 魏NEu 86 98 58 90 __________________________________________________________ 01 //hwk1213.c --- sample program to read studat.txt 02 //========== Originally by tsaiwn@csie.nctu.edu.tw 03 //====== Modified by student_ID student_Name _______________ 04 // You have to modify this program to do this Homework 05 #include <stdio.h> 06 #include <stdlib.h> 07 #include <time.h> 08 #include <math.h> 09 char* fileName = "studat.txt"; // Data File 10 long test( ); 11 void sort( ); // your sorting program according to the score 12 void sort2Print( ); // your another sorting program (照學號) 13 void print( ); // 用來印出資料, 但只印出一部份! 14 int main( ) { 15 long long tStart, tStop; long i, k, n; 16 double tRun; 17 double sum, sumSquare, average, variance, std; 18 test( ); // 這列以上不准改! 19 // 打開檔案讀資料到記憶體, 也可寫成 function 在此 call 它 ! 20 // 一邊讀, 一邊算出每個人的學期總成績; 或讀完再算也可以! 21 // ..注意, 還要算出全部同學的平均 和 標準差 22 printf("Before sort...\n"); 23 print( ); // 叫用 print( ) 印出部份資料 24 // todo.. print average, standard deviation 25 tStart = clock( ); 26 sort( ); // 叫用 你的 sort 程式, 照總成績由高到低 27 tStop = clock( ); 28 tRun = 1.0*(tStop - tStart)/CLOCKS_PER_SEC; 29 printf("...Sorting done in %.5f seconds.\n", tRun); 30 printf("After sort...\n"); 31 print( ); // 叫用 print( ) 印出部份資料 32 // Extra credit: 要有名次, 同分者比期末考, 再同比期中考, .. 33 printf("Now, sorting according to Student_ID ..."); 34 sort2Print( ); // 在裡面做照學號由小到大sort, 注意要測時間 35 fprintf(stderr, "\nHit ENTER key..."); 36 getchar( ); 37 return 0; 38 } 39 void print( ) { // 要用 Global 或是用傳參數的方式自行決定 40 // 印出前面 6 筆 41 printf( " ... " ); // 印出 " ..." 42 // 印出最後 6 筆 43 } 44 void sort( ) { // 要用 Global 或是用傳參數的方式自行決定 45 // insertion sort, selection sort, bubble sort, quick sort ... 46 int i, j, k, gg; // 寫好後請把下列 comment 掉 // 47 // todo ... 48 for(i=1;i<=258;++i)for(k=1;k<= 999999;++k) gg= gg*time(0); 49 } 50 void sort2Print( ) { // 要照學號由小到大 ! 51 // Ascending order, 記得要量時間 52 int i, j, k, gg; // 寫好後請把下列 comment 掉 53 // todo ... 54 for(i=1;i<=123;++i)for(k=1;k<= 999999;++k) gg= gg*time(0); 55 // todo ... sort 好之後把量測到的時間印出來 56 printf("\n === Now already sorted in Student_ID" 57 " at ascending order.\n"); 58 print( ); // call print( ) to print some data 59 } 60 /// do NOT modify the following code 61 long test( ) { // 這函數不准改 ! 62 long id; char name[9]; int s1, s2, s3, s4, kk; 63 char buf[99]; 64 FILE* fp; 65 fp = fopen(fileName, "rt"); // read, text 66 if(fp==0) { // Fail to open it 67 fprintf(stderr, "File %s NOT found!\n", fileName); 68 getchar( ); exit(38); // force to exit with an error 69 } 70 fgets(buf, sizeof(buf), fp); // stdin 71 if(feof(fp) ) { 72 fprintf(stderr, "EOF encounted.\n"); 73 return; 74 } 75 fprintf(stderr, "Line-1: %s\n", buf); 76 fgets(buf, sizeof(buf), fp); // stdin 77 fprintf(stderr, "Line-2: %s\n", buf); 78 s1=s2=s3=s4=0; 79 kk = sscanf(buf,"%ld %s %d %d %d %d", 80 &id, name, &s1, &s2, &s3,&s4); 81 printf("kk=%d\n", kk); 82 if( kk != 4) printf(" something Wrong with data!\n"); 83 printf("id=%ld name = %s\n", id, name); 84 printf("score= %d %d %d %d\n", s1, s2, s3, s4); 85 fprintf(stderr, " counting..."); fflush(stderr); 86 kk = 2; // already read 2 records 87 while(! feof(fp) ) { // 只要檔案還沒結束 88 buf[0] = 0; 89 fgets(buf, sizeof(buf), fp); 90 if( feof(fp) ) { // EOF 也可能有讀到不完整的 Line 91 if(buf[0] == 0) break; // 沒有讀到啦 92 } 93 ++kk; // got one record 94 } 95 fprintf(stderr, " .. done.\nTotal %d records in file %s\n", 96 kk, fileName); // 印到 stderr (螢幕) 97 fflush(stderr); 98 fclose(fp); // close the file 99 return kk; // total kk records in the file 100 } // test(