2018上C语言程序设计(高级)作业- 第3次作业
作业要求一 :
PTA作业的提交列表:
作业要求二:
6-1 输出月份英文名
1.设计思路
(1)主要描述算法:
第一步:本题要求通过字符串指针实现函数,可以返回一个给定月份的英文名称。
第二步:定义整形变量n,通过switch语句,判断每一条语句,如果是就按数字输出月份,否则执行default,输出NULL
第三步:按要求返回主函数并输出。
(2)流程图:
主函数:
调用函数:
2.实验代码:
char *getmonth( int n ) { switch(n) { case 1:return "January"; case 2:return "February"; case 3:return "March"; case 4:return "April"; case 5:return "May"; case 6:return "June"; case 7:return "July"; case 8:return "August"; case 9:return "September"; case 10:return "October"; case 11:return "November"; case 12:return "December"; default:return NULL; } }
3.本题调试过程碰到问题及解决办法
遇到的问题1:应该返回的是指针,而不是字符串。
改正方法:将printf改成return
遇到的问题2:case后面的数字用单引号括了起来。
改正方法:case后面可以是数字,因为switch后面是整形,所以不用单引号。(通过查找课本105页得到答案)
6-2 查找星期
1.设计思路
主要描述算法:
第一步:本题要求用指针数组实现函数,可以根据下表查找到星期,返回对应的序号。
第二步:首先定义一个指针数组,将星期都存到数组里,通过for循环语句和if条件判断(strcmp)比较星期是否相同,break回到上一级,否则返回m。
第三步:按要求输出序号和星期或-1
2.实验代码:
int getindex( char *s ) { int i,m=-1; char *week[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; for(i=0;i<7;i++) { if (strcmp (s, week[i]) == 0) { m=i; break; } } return m; }
3.本题调试过程碰到问题及解决办法
遇到的问题:本题要求传递的应该是字符串,所以不能用switch语句
改正方法:用上课讲的指针数组的方式。
遇到的问题2:在循环中没有先定义m=-1所以总是出现部分正确。
改正方法:先把m=-1定义在前面,再将其赋给i,就不会出现部分正确了。
6-3 计算最长的字符串长度
1.设计思路
主要描述算法:
第一步:本题要求实现一个函数,用于计算有n个元素的指针数组s中最长的字符串的长度
第二步:首先定义整形变量和字符指针数组m,通过两个for循环判断,*(*(s+i)+j)!='\0',继续执行;在第二个for循环中判断如果m[i]>count,输出最长的长度,否则继续循环
第三步:输出指针数组中最长字符串的长度。
2.实验代码:
int max_len( char *s[], int n ) { int i,j,m[20]={0}; int count=0; for(i=0;i<n;i++) { for(j=0;*(*(s+i)+j)!='\0';j++) { } m[i]=j; } for(i=0;i<n;i++) { if(m[i]>count) { count=m[i]; } } return count; }
3.本题调试过程碰到问题及解决办法
遇到的问题:指针*(*(s+i)+j)!='\0'弄错了
改正方法:应该是用指针的指针来判断。
6-4 指定位置输出字符串
1.设计思路
主要描述算法:
第一步:本题要求编写实现函数实现对给定的一个字符串和两个字符,打印出给定字符串中从与第一个字符匹配的位置开始到与第二个字符匹配的位置之间的所有字符
第二步:首先定义整形变量,通过一个for循环先将ch1的值赋给*(s+i);定义指针,判断(*(s+j)!=ch2)&&(*(s+j)!='\0'),如果*(s+j)!='\0',输出,否则返回a
第三步:在大的for循环后输出,再返回s+i的值。
2.实验代码:
char *match( char *s, char ch1, char ch2 ){ int i,j; for(i=0;*(s+i)!='\0';i++) { if(*(s+i)==ch1) { char *a= &s[i]; for(j=i;(*(s+j)!=ch2)&&(*(s+j)!='\0');j++) { printf("%c",*(s+j)); } if(*(s+j)!='\0') printf("%c",*(s+j)); printf("\n"); return a; } } printf("\n"); return s+i; }
3.本题调试过程碰到问题及解决办法
遇到的问题:%c输出的应该是指针*(s+i),而不是s+i
改正方法:将s+i改成*(s+i),程序运行成功。
6-1 奇数值结点链表
1.设计思路
主要描述算法:
第一步:本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。
第二步:在readlist函数中,将输入的值存储在链表里;在while循环内对p进行动态分配内存;当末尾结点的next为空,最后返回链表的头结点。
第三步:根据题目要求的条件对链表结点中date的值进行分类判断,最后按照要求返回要求链表的头结点。
(2)流程图:
调用函数:
调用函数:
调用函数:
2.实验代码:
struct ListNode *readlist() { int number; struct ListNode *p = NULL,*head = NULL,*tail = NULL; scanf("%d",&number); while(number!=-1 && number>0 ) { p = (struct ListNode*)malloc(sizeof(struct ListNode)); p->data = number; if(head == NULL) { head = p; } else { tail->next = p; } tail = p; scanf("%d",&number); } if(head == NULL) { return NULL; } tail->next = NULL; return head; } struct ListNode *getodd( struct ListNode **L ) { struct ListNode *p = *L,*head1 = NULL,*r = NULL,*L1 = NULL,*r1 = NULL; while(p!=NULL && p->data>0) { if(p->data%2!=0) { if(head1 == NULL) { head1 = p; } else { r->next = p; } r = p; } else { if(L1 ==NULL) { L1 = p; } else { r1->next = p; } r1 = p; } p = p->next; } if(head1==NULL) { return NULL; } else { r->next = NULL; } if(L1==NULL) { *L = NULL; } else { r1->next = NULL; *L = L1; } return head1; }
3.本题调试过程碰到问题及解决办法
遇到的问题:在p进行动态分配,开辟新单元的时候,在*后面加了p=L.
改正方法:*号后面应该什么都不加。
6-2 学生成绩链表处理
1.设计思路
主要描述算法:
第一步:本题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。
第二步:在createlist函数中将输入的学号,姓名和分数存储到链表中;当判断学号不为0的情况下输入姓名和成绩,返回链表的头结点。
第三步:在deletelist函数中遍历链表的结点,判断后链表的头结点返回主函数。
2.实验代码:
struct stud_node *createlist() { int num,score; char name[20]; struct stud_node *p,*head=NULL,*tail=NULL; p = (struct stud_node*)malloc(sizeof(struct stud_node)); scanf("%d",&num); while (num != 0) { p = (struct stud_node *)malloc (sizeof (struct stud_node)); scanf ("%s %d", p->name, &p->score); p->num=num; if (head == NULL) head = p; else tail->next = p; tail = p; scanf ("%d", &num); } return head; } struct stud_node *deletelist( struct stud_node *head, int min_score ) { struct stud_node *L=head,*head1=NULL,*tail1=NULL; while(L!=NULL) { if(L->score>=min_score) { if(head1==NULL) { head1 = L; } else { tail1->next = L; } tail1 = L; } L=L->next; } if(head1==NULL) { return NULL; } else { tail1->next =NULL; } return head1; }
3.本题调试过程碰到问题及解决办法
遇到的问题:p->num赋值,判断错了
改正方法:应该将num的值赋给p->num.
6-3 链表拼接
1.设计思路
主要描述算法:
第一步:本题要求实现一个合并两个有序链表的简单函数。
第二步:对本题的理解不是很清楚,就在网上找到相应的类似的题目。大致理解了一下。
第三步:将两个带头结点的链表进行连接,连接后的链表仍然使用原来的存储空间,找到第一个链表的尾节点,使其指针域指向下一个链表的头结点
2.实验代码:
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2) { int num = 0; int temp[100]; struct ListNode *p = list1; while(p != NULL) { temp[num] = p->data; num++; p = p->next; } p = list2; while(p != NULL) { temp[num] = p->data; num++; p = p->next; } int i,j; for(i = 0; i < num; i++) for(j = i + 1; j < num; j++) { if(temp[i] > temp[j]) { int t; t = temp[i]; temp[i] = temp[j]; temp[j] = t; } } struct ListNode *newlist = NULL; struct ListNode *endlist = NULL; struct ListNode *q; for(i = 0; i < num; i++) { q = (struct ListNode *)malloc(sizeof(struct ListNode)); q->data = temp[i]; if(newlist == NULL) { newlist = q; newlist->next = NULL; } if(endlist != NULL) { endlist->next = q; } endlist = q; endlist->next = NULL; } return newlist; }
3.本题调试过程碰到问题及解决办法
遇到的问题:用之前的方法行不通,就到网上找了题目
改正方法:在网上找到解题思路。
要求三、学习总结和进度:
学习总结:
1、总结两周里所学的知识点,回答下列问题?(用自己的话表达出你的理解,网上复制粘贴没有分数)(5分)
(1)如何理解指针数组,它与指针、数组有何关系?为何可以用二级指针对指针数组进行操作?
指针数组是指向内存地址的数组,使用指针数组更节省空间;二维数组定义存在数据区(可更改)
(2)将C高级第三次PTA作业(1)任何一个题目改为使用二级指针对指针数组进行操作。
目前对这一部分的内容掌握得不是很好。
(3)用指针数组处理多个字符串有何优势?可以直接输入多个字符串给未初始化的指针数组吗?为什么?
使用指针数组处理多个字符串更节省空间,因为每个字符串是单独存放的;不可以,未初始化,会出现一些错误;
git的地址:https://git.coding.net/Aspirer1/c3.git
点评同学:
孙铭婧:http://www.cnblogs.com/sun031915/p/8836088.html
张心悦:http://www.cnblogs.com/zxy980612/p/8858885.html
吴晓明:http://www.cnblogs.com/gu-an-cheng-wxm/p/8903685.html
进度表: