第一題:
輸出月份英文名
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:在main中,給你一個月份數字n,要求你通過調用函數char *getmonth,來判斷:若它小於等於12,則將它轉化為英文單詞輸出,若它大於等於12,則輸出wrong input!
3:解答:第一步:定義一個二維數組*a[12][15],並賦值給它1-12月的英文單詞
第二步:定義i,i作為a[]的下標
第三步:利用一個for循環,判斷i是否等於n,若相等,返回a[i-1];若出了for循環,則返回 NULL
流程圖:

實驗代碼:
char *a[12][15]={"January","February","March","April","May","June","July","August","September","October","November","December"};
char *getmonth( int n )
{
int i;
for(i=1;i<=12;i++)
{
if(i==n)
{
return a[i-1];
}
}
return NULL;
}
錯誤信息:

錯誤1: a[12][15]中的號一直沒打,找了好久,害我在其它地方一直改,沒改對
解決方案1:加*號
第二題:
查找星期
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:在main中,給你星期1-7的英文單詞及它們對應的序號,再給你一個字符串,通過調用函數getindex,要你判斷它是否為星期1-7的英文單詞,若是則輸出它的序號,否則輸出wrong input!
3:解答:第一步:定義一個二維數組*a[][],並賦值給它星期7-1的英文單詞
第二步:定義i,i作為a[]的下標
第三步:利用一個for循環,判斷strcmp(s,a[i])是否等於0,若成立,返回序號i;若不成立,跳出for循環后,返回-1
流程圖:

實驗代碼:
char *a[][15]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
int getindex( char *s )
int i;
for(i=0;i<7;i++)
{
if(strcmp(s,a[i])==0)
return i;
}
return -1;
}
錯誤信息:


這題沒錯誤,因為第一題的錯誤避免了,還有我知道strcmp(s,a[i])==0
第三題:
計算最長的字符串長度
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:在main中,題目給你n個字符串,要求你通過調用函數 max_len,計算n個元素的指針數組s中最長的字符串的長度
3:解答:第一步:定義i,max=0,t=0;其中i為s[]的下標,max記錄s中最長的字符串的長度,t為記錄s中字符串的長度
第二步:將strlen(s[0])賦值給max
第三步:利用for循環,從i=1開始,令 t=strlen(s[i]);再判斷max是否小於t,若小於,將t賦值給max,跳出for循環后,返回max
流程圖:

實驗代碼:
int max_len( char *s[], int n )
{
int i,max=0,t=0;
max=strlen(s[0]);
for(i=1;i<n;i++)
{
t=strlen(s[i]);
if(max<t)
max=t;
}
return max;
}
錯誤信息:


無
第四題:
指定位置輸出字符串
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:要你用函數match應打印s中從ch1到ch2之間的所有字符,並且返回ch1的地址
3:解答:在match中,定義i=0,j=0,len=0;i,j作為s[]的下標,len用於記錄s[]長度。還定義 *p=NULL,*p用於記錄ch1的地址
第一步:計算s[]的長度——len = strlen(s)
第二步:用for循環遍歷s[],先找 s[i]==ch1,若找到,則p=&s[i],再用for循環找ch2,若找到,則輸出 ch1到 ch2之間的字符,並返回p;若沒找到,輸出ch1后面的所有字符,並返回p;若沒找到ch1,則p=&s[len],並返回p;
實驗代碼:
char *match( char *s, char ch1, char ch2 ){
int i=0,j=0,len=0;
char *p=NULL;
len = strlen(s);
for(i=0;i<len;i++){
if(s[i]==ch1){
p=&s[i];
for(j=i;j<len;j++){
if(s[j]!=ch2){
printf("%c", s[j]);
}
if(s[j]==ch2){
printf("%c\n", s[j]);
return p;
}
}
printf("\n");
return p;
}
}
p=&s[len];
printf("\n");
return p;
}
錯誤信息:

原因:一開始我題目理解錯了:
我以為在主函數中輸出也是rog,然后我就一直在這個地方錯誤,后來我仔細看題才知道返回的是ch1的地址
第五題:
用篩選法求質數;
題目:

設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:先定義一個宏——MAX_N=10000000,然后定義一個全局變量的數組prime[MAX_N],再定義一個全局變量bool型的數組is_prime[MAX_N+1];
3:在主函數中,先定義b,c,d,i;其中b為你的學號,c為你學號的前三位,d為你學號的后四位,i為prime[]的下標
第一步:輸入你的學號b,然后求出你學號的前三位和學號的后四位——c=b/10000000,d=b%10000;
第二步:調用函數sieve——sieve(c*d);
第三步:輸出
4:在sieve中,用n接收c*d,定義p=0,i,j;p作為質數的下標,i作為數組的下標、還為1—n之間的某個數,j為i的倍數
第一步:用一個for循環,令所以的is_prime[i]的值都為true,出for循環后,令is_prime[0]=is_prime[1]=false;
第二步:用兩個for循環,外層for循環為for( i=2;i<=n;i++),進入外層for循環后,判斷is_prime[i]==true是否成立,若成立,代表i為質數,令prime[p]=i,然后p++,再用一個for循環令所以i的倍數的值全為is_prime[j]=false,實現為內層for循環for(int j=2*i;j<n;j=j+i)is_prime[j]=false;
實驗代碼:基地學長教我的
#include <stdio.h>
#include <math.h>
int MAX_N=10000000;
int prime[MAX_N];
bool is_prime[MAX_N+1];
int sieve(int n){
int p=0,i,j;
for( i=0;i<=n;i++)is_prime[i]=true;
is_prime[0]=is_prime[1]=false;
for( i=2;i<=n;i++){
if(is_prime[i]==true){
prime[p]=i;
p++;
for(int j=2*i;j<n;j=j+i)is_prime[j]=false;
}
}
}
int main()
{
int b,c,d,i;
scanf("%d",&b);
c=b/10000000;
d=b%10000;
int sieve(c*d);
for(i=0;i<=MAX_N;i++)
{
if((i+1)%5==0)
{
printf("%d\n",prime[i]);
}else
{
printf("%d ",prime[i]);
}
}
}
}
第六題:
學生成績鏈表處理
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:在main中,要求你利用兩個函數,一個將輸入的學生成績組織成單向鏈表;另一個將成績低於某分數線的學生結點從鏈表中刪除。其中函數createlist利用scanf從輸入中獲取學生的信息,將其組織成單向鏈表,並返回鏈表頭指針;而函數deletelist從以head為頭指針的鏈表中刪除成績低於min_score的學生,並返回結果鏈表的頭指針;
3:解答:在createlist中,定義三個struct stud_node的指針*p, *ptr, *head=NULL;其中*p用於申請動態空間,*head用於建立鏈表的表頭,*ptr用於建立鏈表的其它部分
第一步:定義num,name[20],score;它們的值用於賦值給struct stud_node結構中的num,name[20],score;
第二步:讀入一個num,並判斷它是否等於0,若不等於,則進入while循環;若等於0,返回head;
第三步:進入whlie后,讀入name[20],score;再申請一個struct stud_node結構的動態空間p,將num,name[20],score的值賦值或復制給p中的num,name[20],score;
第四步:判斷head是否為NULL;是則讓head=p,建立鏈表的表頭;若不是,則令ptr->next = p;出if語句后,再將ptr=p;
第五步:重復操作第二步到第四步,直到num=0,返回head;
在deletelist中,定義二個struct stud_node的指針ptr1, ptr2;在第一個while中,ptr2用於查找從head開始第一個不滿足head->score < min_score的數;在第二個while中(此時的head肯定不滿足head->score < min_score):ptr1用於指向head,ptr2用於指向head的next;
第一步:判斷head != NULL && head->score < min_score,若成立,則令ptr2=head,再令head = head->next,再free(ptr2);若不成立了,一定是以下兩種情況之一:1:學生的分數全部低於min_score,鏈表全部都釋放了,此時head=NULL;
2:找到了第一個學生的分數大於min_score的人,並讓head指向了他;
第二步:出第一個while后,判斷head == NULL;若是,則為我說的第一個情況——學生的分數全部低於min_score,鏈表全部都釋放了,此時head=NULL,應該返回NULL;若不是,則為第二種情況——找到了第一個學生的分數大於min_score的人,並讓head指向了他,我們還要找是否他后面還有不滿足head->score < min_score的數;
第三步:令ptr1 = head;ptr2 = head->next;判斷ptr2 != NULL,若不為空,進入第二個while中,判斷ptr2->score < min_score,若滿足,則說明我們要將ptr1的next釋放,在釋放前,應該先鏈接——ptr1->next = ptr2->next,再釋放——free(ptr2);若不滿足ptr2->score < min_score,則說明ptr2不用被釋放,我們應該讓ptr1指向ptr2——ptr1 = ptr2,再讓ptr2指向ptr1的next——ptr2 = ptr1->next;一直重復下去,直到跳出while
第四步:返回head;
流程圖:
無
實驗代碼:
#include<string.h>
struct stud_node *createlist()
{
struct stud_node *p, *ptr, *head=NULL;
int num;
char name[20];
int score;
scanf("%d",&num);
while (num != 0)
{
scanf("%s %d",name,&score);
p = (struct stud_node *)malloc(sizeof(struct stud_node));
p->num = num;
strcpy(p->name, name);
p->score = score;
p->next = NULL;
if (head == NULL)
{
head = p;
}
else
{
ptr->next = p;
}
ptr = p;
scanf("%d",&num);
}
return head;
}
struct stud_node *deletelist( struct stud_node *head, int min_score )
{
struct stud_node *ptr1, *ptr2;
while (head != NULL && head->score < min_score)
{
ptr2 = head;
head = head->next;
free(ptr2);
}
if (head == NULL)
return NULL;
ptr1 = head;
ptr2 = head->next;
while (ptr2 != NULL)
{
if (ptr2->score < min_score) {
ptr1->next = ptr2->next;
free(ptr2);
}
else
ptr1 = ptr2;
ptr2 = ptr1->next;
}
return head;
}
錯誤信息:

一開始再老師沒講之前,錯誤太多了,不是我們沒做,而是天天在做,天天在錯,刪除鏈表好多情況沒有考慮到,例如:第一個低於min_score;當全部是低於min_score;還有最后一個低於min_score;老師講了之后好一點了,還是有上面的一些問題,最后經過仔細琢磨終於想出想出來了
小結:這題做的太辛苦了,不過嘛,也受到了好多東西,下次在遇到相似的題也不會這么費勁了
第七題:
奇數值結點鏈表
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:在main中,要求你用兩個函數,分別將讀入的數據存儲為單鏈表、將鏈表中奇數值的結點重新組成一個新的鏈表。其中函數readlist從標准輸入讀入一系列正整數,按照讀入順序建立單鏈表。當讀到−1時表示輸入結束,函數應返回指向單鏈表頭結點的指針。而函數getodd將單鏈表L中奇數值的結點分離出來,重新組成一個新的鏈表。返回指向新鏈表頭結點的指針,同時將L中存儲的地址改為刪除了奇數值結點后的鏈表的頭結點地址(所以要傳入L的指針)。
3:解答:在readlist中,定義三個struct ListNode的指針*p, *tail, *head=NULL;其中*p用於申請動態空間,*head用於建立鏈表的表頭,*tail用於建立鏈表的其它部分
第一步:定義data;data的值用於賦值給struct ListNode結構中的data;
第二步:讀入一個data,並判斷它是否等於-1,若不等於,則進入while循環;若等於-1,返回head
第三步:進入whlie后,申請一個struct ListNode結構的動態空間p,將data的值賦給p中的data;p->next=NULL;
第四步:判斷head是否為NULL;是則讓head=p,建立鏈表的表頭;若不是,則令tail->next = p;出if語句后,再將tail=p;
第五步:重復操作第二步到第四步,直到data=-1,返回head;
在getodd中,定義七個struct stud_node的指針*p=*L,*a,*b,*head1,*head2,*p1,*p2;其中head1,head2用於申請動態空間,p用於接收*L,p1用於建立奇數鏈表的表頭,a用於建立奇數鏈表的其它部分,p2用於建立偶數鏈表的表頭,b用於建立偶數鏈表的其它部分
第一步:申請兩個struct ListNode結構的動態空間head1,head2;令a指向head1,b指向head2;
第二步:判斷p!=NULL?,若成立,則p->data%2!=0?,若是,則建立奇數鏈表,否則建立偶數鏈表,若不成立,令*L指向偶數鏈表的表頭p2,返回奇數鏈表的表頭p1;
流程圖:
無
實驗代碼:
struct ListNode *readlist()
{
struct ListNode *head=NULL,*p=NULL,*tail=NULL;
int data;
scanf("%d",&data);
while(data!=-1)
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=data;
p->next=NULL;
if(head==NULL)
{
head=p;
}else
{
tail->next=p;
}
tail=p;
scanf("%d",&data);
}
return head;
}
struct ListNode *getodd( struct ListNode **L )
{
struct ListNode *p=*L,*a,*b,*head1,*head2,*p1=NULL,*p2=NULL;
head1=(struct ListNode*)malloc(sizeof(struct ListNode));
head2=(struct ListNode*)malloc(sizeof(struct ListNode));
head1->next=NULL;
head2->next=NULL;
a=head1;
b=head2;
for(;p!=NULL;p=p->next)
{
if(p->data%2!=0)
{
if(p1==NULL)
p1=p;
else
a->next=p;
a=p;
}
else
{
if(p2==NULL)
p2=p;
else
b->next=p;
b=p;
}
}
a->next=NULL;
b->next=NULL;
*L=p2;
return p1;
}
錯誤信息:

原因:我先是在原來鏈表的基礎上修改,然后建一個奇數鏈表;然而我處理不好,一直錯誤,后來我建了兩個鏈表,一個奇數,一個偶數,最后讓*L=偶數表頭,返回奇數表頭
第八題:
鏈表拼接
設計思路:
1:看題目:主函數與函數聲明,知道它要你干什么
2:理解與分析:在main中,要求你實現一個合並兩個有序鏈表的簡單函數
3:解答:在mergelists中,定義struct ListNode的 *p,*ptr1=list1,*ptr2=list2,*tail=NULL,*head=NULL;其中*p用於申請動態空間,*head用於建立鏈表的表頭,*ptr用於建立鏈表的其它部分,ptr1指向list1,ptr2指向list2;
第一步:定義整形a[1000],i=0,n=0,j=0,t;其中a[]用於儲存list1和list2中的所有數,i,j用於冒泡排序法,n用於記錄a[]有多少數,t用於冒泡排序法中交換的中間量;
第二步:用兩個for循環,將list1和list2中的所有數儲存到a[]中,再用n=i,記錄a[]有多少數;
第三步:用兩個for循環,用冒泡排序法將a[]升序排列;
第四步:建立一個新的鏈表,將a[]的數全部賦值到鏈表中,最后返回鏈表的頭部;
實驗代碼:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2)
{
struct ListNode *p,*ptr1=list1,*ptr2=list2,*tail=NULL,*head=NULL;
int a[1000],i=0,n=0,j=0,t;
for(i=0;ptr1!=NULL;ptr1=ptr1->next,i++)
{
a[i]=ptr1->data;
}
for(;ptr2!=NULL;ptr2=ptr2->next,i++)
{
a[i]=ptr2->data;
}
n=i;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(a[i]>a[j])
{
t=a[i];a[i]=a[j];a[j]=t;
}
}
}
for(i=0;i<n;i++)
{
p=(struct ListNode *)malloc(sizeof(struct ListNode));
p->data=a[i];
p->next=NULL;
if(head==NULL)
{
head=p;
}else
{
tail->next=p;
}
tail=p;
}
return head;
}
錯誤信息:

原因:
有一些NULL沒大寫;寫成了NUll,一直編譯錯誤
總結:
最近兩周的學習,我們學了二級指針,我們利用它輸出月份英文名,查找星期,計算最長的字符串長度,指定位置輸出字符串;我們還學了鏈表,剛開始,感覺建鏈表比較簡單,而刪除鏈表比較困難,因為有些特殊情況不好處理,后來經過不斷的學習,對刪除鏈表也掌握了,這周,我們利用鏈表奇數值結點鏈表,學生成績鏈表處理,鏈表拼接;這周我有一些特別的感覺,以前做PTA基本一下就作好了,而這周嘛,為了這幾題一直在想,一直在做,也許是我掌握的不夠好,不過現在對我來說這種題型都會做了,也可以理解所有代碼,不會像以前那樣費勁了,因為學了一周了,想的也多了,有時走路也在想,感覺這周收獲比較多。我們還學了如何申請動態空間,這樣可以節省更多的空間,上面做的題有體現。
我的進度:


我點評的人:
點評我的人:
左右羽
馬鈺娟
王文博
姜健
李伍壹
