第一題:
輸出月份英文名
設計思路:
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);}elseptr1 = 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;elsea->next=p;a=p;}else{if(p2==NULL)p2=p;elseb->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基本一下就作好了,而這周嘛,為了這幾題一直在想,一直在做,也許是我掌握的不夠好,不過現在對我來說這種題型都會做了,也可以理解所有代碼,不會像以前那樣費勁了,因為學了一周了,想的也多了,有時走路也在想,感覺這周收獲比較多。我們還學了如何申請動態空間,這樣可以節省更多的空間,上面做的題有體現。
我的進度:
我點評的人:
李伍壹
辛靜瑤
姜健
王文博
點評我的人:
左右羽馬鈺娟王文博姜健李伍壹