這個作業屬於哪個課程 | C語言程序設計2 |
這個作業要求在哪里 | 2019年春季學期第九周作業 |
我在這個課程的目標是 | 我希望能夠通過學習C語言的知識,能根據實際情況合理定義結構,能夠使用結構變量與結構數組進行熟練編程,掌握結構指針的操作,並應用於函數傳遞。 |
這個作業在哪個具體方面幫助我實現目標 | 這個作業讓我學會結構的定義,可以使用結構變量與結構數組進行編程,簡單掌握結構指針的操作,並應用於函數傳遞。 |
參考文獻 | 遞歸式求解的三種方法;解遞歸式的方法總結;遞歸的優缺點;C語言程序設計2 |
基礎作業
題目
按等級統計學生成績
本題要求實現一個根據學生成績設置其等級,並統計不及格人數的簡單函數。
函數接口定義:
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
輸出樣例:
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 i,sum;
sum=0;
for(i=0;i<n;i++)
{
if(p[i].score>=0&&p[i].score<=59)
{
p[i].grade='D';
sum++;
}
if(p[i].score>=60&&p[i].score<=69)
{
p[i].grade='C';
}
if(p[i].score>=70&&p[i].score<=84)
{
p[i].grade='B';
}
if(p[i].score>=85&&p[i].score<=100)
{
p[i].grade='A';
}
}
return sum;
}
2)設計思路
用if語句判斷等級,D等級的人數就是不及格的人數,所以判斷一個D,sum就加一。
3)本題調試過程中碰到的問題及其解決辦法
無。
4)運行截圖
題目
一幫一
“一幫一學習小組”是中小學中常見的學習組織方式,老師把學習成績靠前的學生跟學習成績靠后的學生排在一組。本題就請你編寫程序幫助老師自動完成這個分配工作,即在得到全班學生的排名后,在當前尚未分組的學生中,將名次最靠前的學生與名次最靠后的異性學生分為一組。
輸入格式:
輸入第一行給出正偶數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 sex; //性別
char name[20]; //姓名
int flag; //標記
};
int main()
{
struct student a[50];
int i,j,n;
scanf("%d\n",&n);
for(i=0;i<n;i++)
{
scanf("%d %s\n",&a[i].sex,a[i].name);
a[i].flag=0;
}
for(i=0;i<(n/2);i++)
{
for(j=n-1;j>=(n/2);j--)
{
if(a[i].sex!=a[j].sex&&a[i].flag==a[j].flag)
{
printf("%s %s\n",a[i].name,a[j].name);
a[j].flag=1;
break;
}
else
continue;
}
}
return 0;
}
2)設計思路
將學生從正中間分成兩部分,前半部分和后半部分對比,第一個和最后一個對比,性別不同則配對成功。
3)本題調試過程中碰到的問題及其解決辦法
1.格式錯誤,輸入和輸出都沒換行;
解決辦法:在輸入和輸出的格式控制字符串后加上換行符號。
4)運行截圖
題目
考試座位號
每個 PAT 考生在參加考試時都會被分配兩個座位號,一個是試機座位,一個是考試座位。正常情況下,考生在入場時先得到試機座位號碼,入座進入試機狀態后,系統會顯示該考生的考試座位號碼,考試時考生需要換到考試座位就座。但有些考生遲到了,試機已經結束,他們只能拿着領到的試機座位號碼求助於你,從后台查出他們的考試座位號碼。
輸入格式:
輸入第一行給出一個正整數 N(≤1000),隨后 N 行,每行給出一個考生的信息:准考證號
試機座位號
考試座位號
。其中准考證號
由 16 位數字組成,座位從 1 到 N 編號。輸入保證每個人的准考證號都不同,並且任何時候都不會把兩個人分配到同一個座位上。
考生信息之后,給出一個正整數 M(≤N),隨后一行中給出 M 個待查詢的試機座位號碼,以空格分隔。
輸出格式:
對應每個需要查詢的試機座位號碼,在一行中輸出對應考生的准考證號和考試座位號碼,中間用 1 個空格分隔。
輸入樣例:
4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4
輸出樣例:
3310120150912002 2
3310120150912119 1
1)實驗代碼
#include<stdio.h>
struct student{
int adm[16]; //准考證號
int test; //考試座位號
int shiji; //試機座位號
int inq; //待查詢的試機座位號
};
int main()
{
struct student a[1000];
int n,m,i,j;
scanf("%d\n",&n);
for(i=0;i<n;i++)
{
scanf("%s %d %d\n",&a[i].adm,&a[i].shiji,&a[i].test);
}
scanf("%d\n",&m);
for(i=0;i<m;i++)
{
scanf("%d ",&a[i].inq);
}
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(a[i].inq==a[j].shiji)
printf("%s %d\n",a[j].adm,a[j].test);
}
}
return 0;
}
2)設計思路
待查詢的試機座位號用一個變量接收,試機座位號用另一個變量接收,二者做對比,如果相等,就輸出這個試機座位號對應的准考證號和考試座位號。
3)本題調試過程中碰到的問題及其解決辦法
1.答案錯誤,接收准考證號的變量是個整型變量;
解決辦法:把接收准考證號的變量改為長度是16的整型數組,相應輸入輸出的格式控制符改為%s。
4)運行截圖
挑戰作業
題目
九宮格鍵盤對應英語單詞
九宮格鍵盤一般可以用於輸入字母。如用2可以輸入A、B、C,用3可以輸入D、E、F等。如圖所示:
對於號碼5869872,可以依次輸出其代表的所有字母組合。如:JTMWTPA、JTMWTPB……
1.您是否可以根據這樣的對應關系設計一個程序,盡可能快地從這些字母組合中找到一個有意義的單詞來表述一個電話好嗎呢?如:可以用單詞“computer”來描述號碼26678837.
2.對於一個電話號碼,是否可以用一個單詞來代表呢?怎樣才是最快的方法呢?顯然,肯定不是所有的電話號碼都能夠對應到單詞上去。但是根據問題1的解答,思路相對比較清晰。
題目來源:《編程之美——微軟技術面試心得》 稍有修改
這個題有兩個問題,我只對第一個問題有點思路,所以是完全將第二個題的要求排除在外來思考的。
思路:
最近學習了結構,所以想用結構來解這個題。
1.結構成員定義兩個,一個接收鍵盤的數字(只包含字母的數字),一個二維字符數組接收鍵盤的字母。主函數用一個字符數組接收輸入的單詞。
2.遍歷單詞的每個字母,判斷字母與鍵盤上的哪個字母相同,就輸出這個字母所在的鍵的數字;
3.輸出完一個數字之后,跳出循環,判斷單詞的下一個字母。
但是代碼不正確,對一個單詞的判斷只能輸出一個數字2,而且判斷字母E及其之后的字母開頭的單詞,輸出都是空白的,我也不曉得怎么改。
預習作業
1.什么是遞歸函數.
是一個函數,這個函數內部的實行要直接或間接調用這個函數本身,反復調用這個函數自身。例如求階乘,累加等。遞歸函數必須要有結束條件。
2.它的優點和缺點有哪些.
優點:代碼簡潔,易懂。循環能干的事,遞歸都能干;遞歸能干的循環不一定能干。
缺點:效率低下。每次調用函數都要分配空間來保存每一次的局部變量、形參、函數返回地址、返回值,導致空間占用過大,耗費時間太長;遞歸函數存在很多重復計算,所以效率低。
3.如何歸納出遞歸式.
(1)代換法:實質上就是數學歸納法,先對一個小的值做假設,然后推測更大的值得正確性。(2)遞歸樹方法。(3)主方法求解遞歸式。
這三種方法的具體內容我看不太懂,具體看這里
5)預習中存在的疑惑
1.遞歸式的作用是什么;
2.所有的遞歸函數都能計算出精確的值嗎;
3.編程時在遞歸函數和循環結構之間取舍的依據是什么。
結對編程
本周除挑戰題外的其它題目不難,但在和搭檔討論時發現搭檔和我解題的思路不一樣,如果要我按照搭檔的思路來寫代碼的話,我又很難寫出來。結對編程的優點是可以了解一個題目的另一種思路,進而使自己從另一個思考解決問題的方法,缺點是我們對一個題目都沒有思路的時候,就很惆悵。
學習感悟
本周學習了怎樣定義結構,怎樣使用結構變量與結構數組進行編程,學習了結構指針的操作,並應用於函數傳遞。上周預習完之后也把預習題做完了,知道怎么簡單使用結構了,但是對結構的使用形式具體是怎樣的還是感覺很模糊,課上老師把結構比作一張表格,我頓時有種撥開雲霧的感覺,老師的講解真的很重要。本周的難點我認為是在結合題目合理定義結構的成員上,最近的題目都和字符串還有數組有關,對於學號、准考證號定義結構成員時經常搞錯類型,還有字符串,有時不知道是定義成一維字符數組還是二維的又或者是定義成字符變量。這種時候就只有仔細分析題目,如果錯了就多嘗試其它的可能。
學習進度
時間進度條
日期 | 這周所花時間 | 代碼行 | 學到的知識點 | 問題 |
---|---|---|---|---|
3.15-3.22 | 10個小時 | 130 | 選擇排序,冒泡排序,二維數組 | 輸出完一行數后會自動換行嗎 |
3.22-3.29 | 13個小時 | 200 | 字符型數組的簡單使用,字符數組與字符串的區別,二維字符數組的輸入及簡單判斷,對指針的初步了解 | 指針怎樣在自定義函數中返回多個值 |
3.29-4.05 | 8個小時 | 100 | 變量、內存單元和地址之間的關系;如何定義指針變量,怎樣使用指針變量,怎樣進行指針變量的初始化;指針變量的基本運算;理解指針作為函數參數的作用;使用指針實現函數調用返回多個值 | 在自定義函數中將數值賦給指針所指向的變量,要在主函數中輸出該值,輸出參數是指針,為什么不可以。 |
4.05-4.12 | 12個小時 | 150 | 數組名作為函數參數的用法,指針、數組和地址之間的關系,指針和數組可以實現相同的操作,strcpy函數的深層理解,for循環與while循環在內存層面的區別 | 對指針的運用不熟練 |
4.12-4.19 | 8個小時 | 120行 | 常用字符串函數,如何使用指針操作字符串,動態內存分配。 | 兩個字符串的交換為什么不能通過賦值實現 |
4.19-4.26 | 10個小時 | 120行 | 使用結構變量與結構數組進行編程,利用結構指針進行操作,並應用於函數傳遞 | 有些題目不用結構也能解決,在二者都能解決的情況下,使用結構解決問題有什么優勢 |
時間 | 累計代碼行數 | 累計博客字數 |
---|---|---|
第一周 | 80 | 0 |
第二周 | 150 | 400 |
第三周 | 250 | 1600 |
第四周 | 380 | 3200 |
第五周 | 580 | 5110 |
第六周 | 680 | 8110 |
第七周 | 830 | 10910 |
第八周 | 950 | 13510 |
第九周 | 1070 | 17210 |