資料結構實訓——成績統計系統
1 課題描述
給出n個學生的m門考試的成績表,每個學生的資訊由學號、姓名以及各科成績組成。對學生的考試成績進行有關統計,並列印統計表。
2 問題分析和任務定義
(1) 按總分數高低次序,打印出名次表,分數相同的為同一名次;
(2) 按名次打印出每個學生的學號、姓名、總分以及各科成績。
(3) 注意測試邊界資料。
(4) 對各科成績設定不同的權值。(附加功能)
3 邏輯設計
1)資料型別:
對於學生所包含的資訊,學號使用整數型,姓名使用字串型,各科成績和總成績還有加權成績使用浮點型。同時設定浮點型陣列來儲存各科所佔權值的比率,設定整數型陣列來儲存每個學生的排名。
struct STU
{
int id;///學號
char name[20];///姓名
float score[20];///成績
float rsum;///加權後的總分
float sum;///不加權的總分
}s[110];
float ratios[30];///權值比率
int rerank[100];///學生排名
2)抽象資料型別
ADT Stu{
資料物件D:D是具有相同特徵的資料元素的集合。各資料元素均含有型別相同,可唯一標識資料元素的關鍵字。
資料關係R:資料元素同屬一個集合。
input(int n,int m)
操作結果:輸入n個學生的學號,姓名,m科成績。
quick_sort(int n)
操作結果:對n個學生按加權總分進行快速排序。
ranks(int n,int rerank[])
操作結果:對n個學生進行排名,加權總分相同的,獲得相同的名次。
display(int n,int m,int rerank[])
按照排名列印n個學生的學號、姓名、總分和各科分數。
}ADT Stu
3)模組功能:
功能上分為輸入、排序、排名、列印這三大模組。其中排序模組中需要使用排序演算法給學生按照加權成績排名。排名模組需要編寫演算法實現相同分數排名相同的要求。
4 詳細設計
學生資訊結構體:
struct STU
{
int id;///學號
char name[20];///姓名
float score[20];///成績
float rsum;///加權後的總分
float sum;///不加權的總分
}s[110];
<1>輸入函式: void input(int n,int m)
輸入n個學生的學號,姓名,m科成績。
<2>快速排序函式:void quick_sort(int n)
對n個學生按加權總分進行快速排序。
<3>相同名次處理:void ranks(int n,int rerank[])
對n個學生進行排名,加權總分相同的,獲得相同的名次。
<4>列印函式void display(int n,int m,int rerank[])
按照排名列印n個學生的學號、姓名、總分和各科分數。
5程式編碼
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct STU { int id;///學號 char name[20];///姓名 float score[20];///成績 float rsum;///加權後的總分 float sum;///不加權的總分 }s[110]; int my_cmp(STU a,STU b) { if(a.rsum>=b.rsum)///按照加權後的總分來排序 { return 1; } else { return 0; } } void input(int n,int m) { int i,j; printf("請輸入學生的學號、姓名和各科成績\n"); for(i=0; i<n; i++) { scanf("%d",&s[i].id); scanf(" %s",&s[i].name); for(j=0; j<m; j++) { scanf("%f",&s[i].score[j]); } } } void quick_sort(int n) { sort(s,s+n,my_cmp);///STL庫中的快速排序演算法 } void ranks(int n,int rerank[]) { int i,k; k=0; for(i=0;i<n;i++) { if(s[i].rsum==s[i-1].rsum) { rerank[i]=k; } else { k++; rerank[i]=k; } } } void display(int n,int m,int rerank[]) { int i,j; printf("依次列印排名、學號、姓名、總分、加權總分和各科分數\n"); for(i=0; i<n; i++) { printf("%d ",rerank[i]); printf("%d ",s[i].id); printf("%s ",s[i].name); printf("%.2f ",s[i].sum); printf("%.2f ",s[i].rsum); for(j=0; j<m; j++) { printf("%.2f ",s[i].score[j]); } printf("\n"); } } int main() { int n,m,i,j; float ratios[30]; int rerank[100]; printf("請輸入學生人數n:\n"); scanf("%d",&n); printf("請輸入考試科目數m:\n"); scanf("%d",&m); printf("請依次輸入各科的權重\n"); for(i=0; i<m; i++) { scanf("%f",&ratios[i]); } input(n,m); for(i=0; i<n; i++)///計算加權的總分和非加權的總分 { for(j=0; j<m; j++) { s[i].rsum+=s[i].score[j]*ratios[j]; s[i].sum+=s[i].score[j]; } } quick_sort(n); ranks(n,rerank); display(n,m,rerank); return 0; }
6 程式除錯與測試