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(