1. 程式人生 > >資料結構實訓——成績統計系統

資料結構實訓——成績統計系統

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{

資料物件DD是具有相同特徵的資料元素的集合。各資料元素均含有型別相同,可唯一標識資料元素的關鍵字。

資料關係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 程式除錯與測試