2019春第九周做業


這個做業屬於哪一個課程 C語言程序設計
這個做業的要求在哪裏 https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018/homework/3124
我在這個課程的目標是 可以根據實際狀況合理定義結構,可以使用結構變量與結構數組進行熟練編程,掌握結構指針的操做,並應用於函數傳遞
這個做業在哪一個具體方面幫助我實現目標 能熟練進行結構變量的定義和初始化,熟練運用結構變量解決問題
參考文獻 C語言程序設計

一.基礎題

6-1 按等級統計學生成績 (20 分)

本題要求實現一個根據學生成績設置其等級,並統計不及格人數的簡單函數。
函數接口定義:html

int set_grade( struct student *p, int n );

其中p是指向學生信息的結構體數組的指針,該結構體的定義爲:算法

struct student{
    int num;
    char name[20];
    int score;
    char grade;
};

n是數組元素個數。學號num、姓名name和成績score均是已經存儲好的。set_grade函數須要根據學生的成績score設置其等級grade。等級設置:85-100爲A,70-84爲B,60-69爲C,0-59爲D。同時,set_grade還須要返回不及格的人數。
裁判測試程序樣例:編程

#include <stdio.h>
#define MAXN 10

struct student{
    int num;
    char name[20];
    int score;
    char grade;
};

int set_grade( struct student *p, int n );

int main()
{   struct student stu[MAXN], *ptr;
    int n, i, count;

    ptr = stu;
    scanf("%d\n", &n);
    for(i = 0; i < n; i++){
       scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
    } 
   count = set_grade(ptr, n);
   printf("The count for failed (<60): %d\n", count);
   printf("The grades:\n"); 
   for(i = 0; i < n; i++)
       printf("%d %s %c\n", stu[i].num, stu[i].name, stu[i].grade);
    return 0;
}

/* 你的代碼將被嵌在這裏 */

輸入樣例:數組

10
31001 annie 85
31002 bonny 75
31003 carol 70
31004 dan 84
31005 susan 90
31006 paul 69
31007 pam 60
31008 apple 50
31009 nancy 100
31010 bob 78

輸出樣例:app

The count for failed (<60): 1
The grades:
31001 annie A
31002 bonny B
31003 carol B
31004 dan B
31005 susan A
31006 paul C
31007 pam C
31008 apple D
31009 nancy A
31010 bob B

1)運行代碼

int set_grade( struct student *p, int n )
{
    int h=0;
    //設置等級 
    for(int i=0;i<n;i++,p++){
        if(p->score<=100&&p->score>=85){
            p->grade='A';
        }else if(p->score<=84&&p->score>=70){
            p->grade='B';
        }else if(p->score<=69&&p->score>=60){
            p->grade='C';
        }else if(p->score<=59&&p->score>=0){
            p->grade='D';
            //統計不及格人數
            h++; 
        }
    }
    return h; 
}

2)設計思路

3)本題調試過稱中遇到的問題及解決辦法

本題比較簡單,一次性經過,沒有遇到問題.函數

4)運行截圖

7-1 一幫一 (15 分)

「一幫一學習小組」是中小學中常見的學習組織方式,老師把學習成績靠前的學生跟學習成績靠後的學生排在一組。本題就請你編寫程序幫助老師自動完成這個分配工做,即在獲得全班學生的排名後,在當前還沒有分組的學生中,將名次最靠前的學生與名次最靠後的異性學生分爲一組。
輸入格式:
輸入第一行給出正偶數N(≤50),即全班學生的人數。此後N行,按照名次從高到低的順序給出每一個學生的性別(0表明女生,1表明男生)和姓名(不超過8個英文字母的非空字符串),其間以1個空格分隔。這裏保證本班男女比例是1:1,而且沒有並列名次。
輸出格式:
每行輸出一組兩個學生的姓名,其間以1個空格分隔。名次高的學生在前,名次低的學生在後。小組的輸出順序按照前面學生的名次從高到低排列。
輸入樣例:性能

8
0 Amy
1 Tom
1 Bill
0 Cindy
0 Maya
1 John
1 Jack
0 Linda

輸出樣例:學習

Amy Jack
Tom Linda
Bill Maya
Cindy John

1)實驗代碼

#include<stdio.h>
#include<string.h>

//學生 
struct student{
    //性別
    int s; 
    //姓名
    char name[9];
};

//組員
struct zuyuan{
    char names[9];
    char named[9]; 
};
 
int main()
{
    struct student stu[50];
    struct zuyuan stud[50];
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d %s",&stu[i].s,stu[i].name);
    }
    //匹配
    //先將排名前一半學生的從第一名開始,將姓名依次儲存在結構數組的第一位組員 
    for(int i=0;i<n/2;i++){
        strcpy(stud[i].names,stu[i].name);
    }
    
    //再從全班後一半,從最後一位開始循環和第一位組員比較性別 
    for(int i=0;i<n/2;i++){
        for(int j=n-1;j>=n/2;j--){
            //若性別不一樣,且沒有和別的組員匹配 
            if(stu[i].s!=stu[j].s&&stu[j].s!=3){
                //將姓名儲存在第二位組員 
                strcpy(stud[i].named,stu[j].name);
                //若已經匹配了,則改變性別 
                stu[j].s=3;
                //匹配完後,跳出內循環,以避免又和下一位異性匹配 
                break;
            }
        }
    }
    for(int i=0;i<n/2;i++){
        printf("%s %s\n",stud[i].names,stud[i].named);
    } 
}

2)設計思路

3)本題調試過稱中遇到的問題及解決辦法

這題比較難,剛看到的時候連思路都沒有,後來慢慢相出思路,既然男女比例爲一比一,則全班人數爲偶數,那先將排名前一半的每一個人分爲第一位組員,而後和後一半的異性匹配,但一開始我不知道怎樣將已經匹配了的人和沒有匹配的區分,否則就會有人和多我的匹配,後來想到了兩種方法,一是將已經匹配的人的性別該成不男不女,或者在表示學生信息的構造函數里加一個成員變量,用它來判斷該學生是否已經匹配。測試

4)運行截圖

7-2 考試座位號 (15 分)

每一個 PAT 考生在參加考試時都會被分配兩個座位號,一個是試機座位,一個是考試座位。正常狀況下,考生在入場時先獲得試機座位號碼,入座進入試機狀態後,系統會顯示該考生的考試座位號碼,考試時考生須要換到考試座位就座。但有些考生遲到了,試機已經結束,他們只能拿着領到的試機座位號碼求助於你,從後臺查出他們的考試座位號碼。
輸入格式:
輸入第一行給出一個正整數 N(≤1000),隨後 N 行,每行給出一個考生的信息:准考證號 試機座位號 考試座位號。其中准考證號由 16 位數字組成,座位從 1 到 N 編號。輸入保證每一個人的准考證號都不一樣,而且任什麼時候候都不會把兩我的分配到同一個座位上。
考生信息以後,給出一個正整數 M(≤N),隨後一行中給出 M 個待查詢的試機座位號碼,以空格分隔。
輸出格式:
對應每一個須要查詢的試機座位號碼,在一行中輸出對應考生的准考證號和考試座位號碼,中間用 1 個空格分隔。
輸入樣例:.net

4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4

輸出樣例:

3310120150912002 2
3310120150912119 1

1)實驗代碼

#include<stdio.h>
#define MAXN 1000
struct student{
    char str[17];
    int s;
    int k;
};
int main()
{
    struct student stu[MAXN];
    int n,m,x[MAXN];
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s %d %d",stu[i].str,&stu[i].s,&stu[i].k);
    }
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%d",&x[i]);
    }
    //查詢
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(x[i]==stu[j].s){
                printf("%s %d\n",stu[j].str,stu[j].k);
                break;
            }
        }
    }
}

2)設計思路

3)本題調試過稱中遇到的問題及解決辦法


我照着函數題寫了一個#define MAXN 10,後發現不對,上網查知道#define nmax 50,這句話的含義是:定義一個宏nmax 下面凡是遇到該符號的位置,替換爲50,示例:chara[nmax]; 等價於char a[50];可是這個並不是字符串替換,下面的狀況是不會被宏影響的:int var_nmax = 0;不會被替換可是下面的狀況會被替換,同時致使編譯錯誤int nmax=0; 會被替換爲 int 50=0;

4)運行截圖

二.預習題

1.什麼是遞歸函數?

在函數調用中,若是直接或間接地調用該函數自己,稱爲遞歸調用,但必須得有一個判斷結束的條件,不然都成了死循環!

2.它的優勢和缺點有哪些?

優勢:代碼簡潔,
缺點:
效率低下,容易致使棧溢出。
a.遞歸因爲是函數調用自身,而函數調用是有時間和空間的消耗的:每一次函數調用,都須要在內存棧中分配空間以保存參數、返回地址以及臨時變量,而往棧中壓入數據和彈出數據都須要時間。->效率
b.遞歸中不少計算都是重複的,因爲其本質是把一個問題分解成兩個或者多個小問題,多個小問題存在相互重疊的部分,則存在重複計算,如fibonacci斐波那契數列的遞歸實現。->效率
c.調用棧可能會溢出,其實每一次函數調用會在內存棧中分配空間,而每一個進程的棧的容量是有限的,當調用的層次太多時,就會超出棧的容量,從而致使棧溢出。->性能
取自:(https://blog.csdn.net/wangzhenling/article/details/59702845)

3.如何概括出遞歸式?

網上說好像有三種方法,但我看不懂,因此只能引用網友的一些文字。
三種方法:代入法、遞歸樹法和主方法。
代入法:
定義:先猜想某個界的存在,再用數學概括法去證實該猜想的正確性。
缺點:只能用於解的形式很容易猜的情形。
總結:這種方法須要經驗的積累,能夠經過轉換爲先前見過的相似遞歸式來求解。
遞歸樹法:
原由:代換法有時很可貴到一個正確的好的猜想值。
用途:畫出一個遞歸樹是一種獲得好猜想的直接方法。
分析(重點):在遞歸樹中,每個結點都表明遞歸函數調用集合中一個子問題的代價。將遞歸樹中每一層內的代價相加獲得一個每層代價的集合,再將每層的代價相加獲得遞歸式全部層次的總代價。
總結:遞歸樹最適合用來產生好的猜想,而後用代換法加以驗證。
遞歸樹的方法很是直觀,總的代價就是把全部層次的代價相加起來獲得。可是分析這個總代價的規模卻不是件很容易的事情,有時須要用到不少數學的知識。
主方法:
主方法是最好用的方法,書本上以」菜譜「來描述這種方法的好用之處,它能夠瞬間估計一個遞推式的算法複雜度。可是咱們知道,這後面確定是嚴格的數學證實在支撐着,對於咱們用戶來講,咱們只用知道怎麼用就好了。
優勢:針對形如T(n) = af(n/b) + f(n)的遞歸式
缺點:並不能解全部上述形式的遞歸式,有一些特殊狀況,見下文分析。
分析:三種狀況,以下圖,着重看圈線的部分:

直覺:看 f(n) 和 nlogba 的關係,誰大取誰,相等則兩個相乘,但要注意看是否相差因子 nε。對於3),還要看是否知足條件 af(n/b) <= cf(n) .
就像上面所說的,該方法不能用於全部的形如上式的遞歸式,f(n)和nlogba的關係必須是多項式意義上的小於大於,即漸近關係(漸近小於、漸近大於),什麼是漸近,就是二者相差一個因子nε。因此,在狀況1和狀況2之間有必定的間隙,一樣狀況2和請看3之間也有必定的間隙;對於狀況3,還要看是否知足正則條件。
取自:(http://www.javashuo.com/article/p-vesaxalb-bx.html) 

三.預習的主要內容

1.函數的嵌套使用
2.遞歸函數基本概念
3.遞歸程序設計

四.學習進度條


周/日期 這周所花的時間 代碼行 學到的知識點簡介 目前比較迷惑的問題
2/25-3/3 6h 39 一維數組的定義和引用及初始化 字符數組和整型數組的區別
3/4-3/10 12h 47 指針的定義及運用;文件的讀取、寫入, 處理和開關;文件的打開方. 文件的分類,什麼是文本文件, 什麼是二進制文件;字符數組的讀取和寫入
3/11-3/17 6h 57 二維數組的定義及應用 二維數組的行和列的嵌套循環輸入和輸出
3/18-3/24 12h 98 選擇排序法、冒泡排序法和二分查找法 不清楚選擇排序法和冒泡排序法的區別
3/25-3/31 20h 88 字符數組和字符串的區別,字符串的輸入輸出方式和格式,二維數組更高級的運用。 不清楚指針在程序中的做用
4/1-4/7 12h 70 變量、內存單元和地址之間的關係;指針變量的定義及初始化,指針變量的基本運算,指針、數組和地址間的關係 二分法查找法不太明白
4/8-4/14 11h 99 掌握數組名做爲函數參數的用法,理解指針、數組和地址之間的關係,理解指針和數組能夠實現相同的操做 好像忘記了,可能沒有
4/15-4/21 12h 132 掌握經常使用字符串函數以及使用指針操做字符串的方法,掌握動態內存分配 各個動態內存分配函數的區別仍是不太清楚
4/22-4/28 12h 133 合理定義結構,使用結構變量與結構數組編程,掌握結構指針的操做,並應用於函數傳遞 解遞歸式的三種方法不太理解

五.學習感悟

這周基礎題還好,除了編程題第二題比較難外,其它的不算很難,可是預習題改變了方式,還不太適應,若預習題是編程題,我或許還能作出來,但要我寫對預習內容的理解,我真的寫不出什麼話來,我語文成績一直很差,總感受只可意會不可言傳。

六.結對編程感想

過程:此次結對編程在預習題的第二題上討論了好久,花的時間比較長 ,主要是討論這題的思路是怎樣的; 而後就是預習題的理解, 前兩個問題咱們倆都搞明白了, 但最後一個問題咱們倆都搞不明白, 看網友的解釋都以爲腦袋疼。
感想:感受此次結對編程還行,咱們兩我的對每一個題目都有不一樣的理解,不一樣的思路,而後咱們在這兩種方法中選最好的一種方法,或將兩種方法結合起來,找到一個比原兩種方法都要好的方法。

七.表格和折線圖


時間 代碼行數 博客字數
第一週 39 1754
第二週 47 2087
第三週 57 1993
第四周 98 2145
第五週 88 2472
第六週 70 2514
第七週 99 3127
第八週 132 3313
第九周 133 2897

相關文章
相關標籤/搜索