2018上C语言程序设计(高级)作业- 第3次作业
作业要求一
6-1 输出月份英文名
6-2 查找星期
6-3 计算最长的字符串长度
6-4指定位置输出字符串
6-5奇数值结点链表
6-6学生成绩链表处理
6-7链表拼接
作业要求二
- 题目6-1输出月份英文名
1、设计思路
(1)第一步:根据题目要求,由给定的数字来返回月份,首先要定义一个字符数组来包含各个月份的英文名。(注意各个月份的英文名一定要输入正确,最好是复制粘贴)
第二步:定义完字符数组之后,便可以通过遍历的方法来找出所对应的月份(因为传入的是整型的,便可利用其与同为整型的循环变量进行比较判断,同时要注意循环变量为0的时候,此时应该输出没有相应的月份)
第三步:在根据题目的要求上说的不是1-12的数字之外的输出“wrong input!”,便通过“if”条件语句进行判断来限制这个条件;
2、实验代码
#include <stdio.h>
char *getmonth( int n )
{
char *month[13]={"January","February","March","April","May","June","July","August","September","October","November","December"};
int i=0;
for(i=0;i<13;i++)
{
if(i==0)
{
continue;
}else if(n==i)
{
return *(month+i-1);
}
}
if(n>=13||n<=0)
{
return NULL;
}
}
3、本题调试过程碰到问题及解决办法
错误信息1:本题本来是没有问题的,但是在提交的过程中总是有一个点过不了,从我的PTA的提交情况也可查看
改正方法:这个错误非常的隐蔽,我当时因为这个问题花费了整整两节课的时间,也请教了不少的同学,但是都说我的代码没有问题,都非常的不解,最后通过对比我的英文单词才发现我的二月写错了,之后便改正成功了,非常的尴尬。
-
题目6-2查找星期
1、设计思路
(1)第一步:根据题目要求,本题和第一个题很相似,可类比上一题进行推理,首先还是要定义一个字符数组;(注意各个单词拼写)
第二步:之后开始遍历数组进行查找,根据题目的要求返回的是一个整型元素,而在编写的函数里定义的数组是字符类型的,便可通过同为整型的循环变量来解决这个问题,即当查找到相对应的星期之后,便返回所对应的循环变量即可;
(2)流程图:
2、实验代码:
#include <stdio.h>
#include <string.h>
#define MAXS 80
int getindex( char *s )
{
char *a[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
int i=0,result=-1;
for(i=0;i<7;i++)
{
if(strcmp(s,a[i])==0)
{
result=i;
}
}
return result;
}
3、本题调试过程碰到问题及解决办法
错误信息1:本题我的错误在我定义了一个用来返回的变量,因为我的一些习惯性操作,把这个变量一开始赋初始值为0,而在题目的要求是要求但返回值为-1是为NULL,所以我当时这个问题出现了错误;
改正方法:这个问题很好的解决,我就是把我所定义的变量赋初始值为-1即可解决;
- 题目6-3计算最长的字符串长度
1、设计思路
(1)第一步:本题要计算字符串的最长的长度,便可想到在字符串里有个计算字符串长度的函数strlen,可通过此函数进行比较;
第二步:根据此原理,通过遍历所给的字符串数组,通过if条件判断的方式进行逐一的比较判断,即可找出最长的字符串长度;
2、实验代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXN 10
#define MAXS 20
int max_len( char *s[], int n )
{
int max=0,j=0,len=0;
for(j=0;*(s+j)!='\0';j++)
{
len=strlen(*(s+j));
if(max<len)
{
max=len;
}
}
return max;
}
3、本题调试过程碰到问题及解决办法
本题在调试过程中没有遇到问题;
- 题目6-4指定位置输出字符串
1、设计思路:
(1)第一步:根据题意,要先查找输出指定的字符串,首先要定义循环变量,通过遍历来进行查找;
第二步:在查找之前需要定义一个指针,用它来指向所传入的所让输入的数组的首地址,之后根据传入的字符进行判断,如果在遍历过程中和第一个传入的字符相同便把它赋给指针,之后再次前提下再次进行遍历,找出在此字符数组中和第二个字符相同的字符;并进行输出;
第三步:最后需要判断一种只有第二个字符,而没有第一个字符的情况,故需加上若原字符数组为空,并返回元字符数组的首地址;
2、实验代码
char *match( char *s, char ch1, char ch2 )
{
int i=0,j=0;
char *p=NULL;
for(i=0;*(s+i)!='\0';i++)
{
if(s[i]==ch1)
{
p=&s[i];
for(j=i;*(s+j)!='\0';j++)
{
if(s[j]!=ch2)
{
printf("%c", s[j]);
}
if(s[j]==ch2)
{
printf("%c\n", s[j]);
return p;
}
}
printf("\n");
return p;
}
}
if(s[i] == '\0')
p = &s[i];
printf("\n");
return p;
}
3、本题调试过程碰到问题及解决办法
错误信息1: 本题在调试过程中,此题并不是太懂,至今也是不是很懂,起初写完之后,提交过程总是显示着部分正确,其中就是那个若传入的第一个字符没有,而给的第二个字符有的情况,当时我没有加程序的最后几段程序,也不知道到底哪里出现错误,感觉输出的没有问题;
改正方法:后来请教同学,才知道,我以前那个在测试上述的情况时不加那几行代码会少一行空格,加上后便可以正常输出;
- 一道编程题
1、设计思路:
第一步:首先根据题目要求要定义两个变量,来储存自己所输入的值,之后,由于所计算的值很大,需要进行动态分配空间;
第二步:分配完空间之后,在定义一个数组,通过遍历的方式进行挨个赋值;
第三步:之后再按照题目所说的要求进行查找判断出所要找的数值;
第四步:最后通过遍历进行输出;
2、实验代码:
#include<stdio.h>
int main()
{
int m=0,n=0,i=0,j=0,flag=0;
scanf("%d %d",&m,&n);
flag=m*n;
int *p = (int *)malloc((m*n) *sizeof(int));
int *q = (int *)malloc((m*n) *sizeof(int));
for(i=0;i<flag;i++)
{
p[i] = i+1;
}
for(i=0;i<flag;i++) {
for(j = i+1;j<=flag;j++) {
if(p[i] !=1&&p[j] != 1) {
if(p[j]%p[i] ==0) {
p[j] = 1;
}
}
}
}
j=0;
for(i=0;i<flag;i++) {
if(p[i] != 1) {
printf(" %d",p[i]);
j++;
}
if(j == 5) {
printf("\n");
j=0;
}
}
}
3、本题在调试过程中遇到的问题
错误信息1:本题在调试过程中遇到的问题是由于所储存的元素很大,而系统分配的不合理,在运行的时候总是出现系统崩溃的现象,写的程序总是运行不出来;
改正方法:在出现这个问题之后,想到老师上课讲的内存的问题,但是自己也只能知道问题出现在哪里,但不知道怎么去改正,后来请教同学之后怎么去进行动态分配;
- 题目6-5 奇数值结点链表
1、设计思路
第一步:本题需要两个函数,第一个函数是进行链表的输入,在输入时,首先需要进行定义所需的结构体变量,之后在定义结构体中所需要的各个变量;之后再进行输入操作,通过while判断,进行给链表的单向赋值,在赋值时,还需要进行动态分配内存的操作,最后返回头指针;
第二步:本题的第二个函数就是进行奇数与偶数的分离,大体上是通过两个链表进行分离。
第三步:通过while判断所传入的链表中的data是否能被2所整除,来进行奇偶的分离;最后返回头指针;
2、实验代码
struct ListNode *readlist()
{
struct ListNode *p=NULL,*tail=NULL,*head=NULL;
int data=0,count=0;
p=tail=(struct ListNode*)malloc(sizeof(struct ListNode));
scanf("%d",&data);
while(data!=-1)
{
p->data=data;
p->next=NULL;
count++;
if(count==1)
{
head=p;
}else
{
tail->next=p;
tail=p;
}
p=(struct ListNode*)malloc(sizeof(struct ListNode));
scanf("%d",&data);
}
return head;
}
struct ListNode *getodd( struct ListNode **L )
{
struct ListNode *i=NULL,*head1=NULL,*head2=NULL,*m=NULL,*n=NULL;
i=*L;
head1=(struct ListNode*)malloc(sizeof(struct ListNode));
head2=(struct ListNode*)malloc(sizeof(struct ListNode));
head1->next=NULL;
head2->next=NULL;
m=head1;
n=head2;
while(i)
{
if(i->data%2!=0)
{
m->next=i;
m=i;
}else
{
n->next=i;
n=i;
}
i=i->next;
}
m->next=NULL;
n->next=NULL;
*L=head2->next;
return head1->next;
}
3、本题调试过程碰到问题及解决办法
错误信息1:本题在调试的过程中,由于当时是还没有学习相应的链表的各种插入、删除等等的操作,再加上在当时上完课之后,对链表了解的不深刻,自己也就只能写出链表的输入;对题目中要求的奇数和偶数的操作自己是几乎不会;
改正方法:自己去网上查了下有关链表的内容,自己再试了试,感觉可以通过定义两个链表进行操作;
- 题目6-6 学生成绩链表处理
1、设计思路:
第一步:首先要定义一个进行赋值的函数,此函数和普通的赋值区别不大,都是一般的先定义结构体变量,之后再进行输入赋值,并返回头指针;
第二步:在定义第二个函数中,根据题目要求,我有两种思路,第一种思路是在定义一个结构体变量,通过遍历查找出所需要的元素并将其传给所定义的变量中去;第二种思路是根据老师上课讲的删除,通过遍历查找出不符合要求的进行删除;此题我应用的是第一种方法,通过遍历找出所需的变量,并返回;
2、实验代码:
struct stud_node *createlist()
{
struct stud_node *tail=NULL,*head=NULL,*p=NULL;
int num=0,score=0;
char name[20];
scanf("%d",&num);
while(num!=0)
{
p=(struct stud_node*)malloc(sizeof(struct stud_node));
p->num=num;
scanf("%s %d",p->name,&p->score);
if(head==NULL)
{
head=p;
}else
{
tail->next=p;
}
tail=p;
scanf("%d",&num);
p->next=NULL;
}
return head;
}
struct stud_node *deletelist( struct stud_node *head, int min_score )
{
struct stud_node *ptr1=NULL,*ptr2=NULL;
for(;head!=NULL;head=head->next)
{
if(head->score>=min_score)
{
if(ptr1==NULL)
{
ptr1=head;
}else
{
ptr2->next=head;
}
ptr2=head;
}
}
if(ptr1==NULL)
{
return NULL;
}else
{
ptr2->next=NULL;
}
return ptr1;
}
3、本题在调试过程中遇到的问题
错误信息1:本题在未上本周最后一节C语言课之前我的想法就是第一种,但当时我只是进行的简单的定义,用if语句判断出所需的要求就进行赋值,但其实那是错误的,只是错误的按照数组的方法进行操作。
改正方法:在上完最后一节课之后,我觉得这个题可以用删除的方法做,但是模仿做了一点就不太会了,便放弃了这种做法,又重新改为第一种方法,这时我在赋值的时候又重新按照第一个函数进行赋值的操作那样进行赋值,最后运行成功。
- 题目6-7链表拼接
1、设计思路
第一步: 根据题目要求,题目是进行链表排序,又因本题定义的结构体中只有一种整数类型,所以我们可以,先定义一个数组,先将链表里的数据储存在数组中,之后再通过数组进行排序操作;
第二步:数组排序完之后,再通过for语句遍历的进行把数组里的值重新赋给链表;
2、实验代码
struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2)
{
int list[100],i=0,j=0,swap=0,count=0;
while(list1!=NULL)
{
list[i]=list1->data;
i++;
list1=list1->next;
count++;
}
while(list2!=NULL)
{
list[i]=list2->data;
i++;
list2=list2->next;
count++;
}
for(i=0;i<count;i++)
{
for(j=i+1;j<count;j++)
{
if(list[i]>list[j])
{
swap=list[i];list[i]=list[j];list[j]=swap;
}
}
}
struct ListNode *p=NULL,*head=NULL,*tail=NULL;
for(i=0;i<count;i++)
{
p=(struct ListNode*)malloc(sizeof(struct ListNode));
p->data=list[i];
p->next=NULL;
if(head==NULL)
{
head=p;
}else
{
tail->next=p;
}
tail=p;
}
return head;
}
3、本题调试过程中遇到的问题
本题没有问题;
要求三、学习总结和进度
1、总结两周里所学的知识点,回答下列问题?(用自己的话表达出你的理解,网上复制粘贴没有分数)
(1)如何理解指针数组,它与指针、数组有何关系?为何可以用二级指针对指针数组进行操作?
指针数组,自我理解是数组里的每个元素都是指针,每个元素都是指向着地址;用二级指针可以对指针数组操作,我认为这是因为他们都指向着相同的地址,都是对地址值进行操作。
(2)将C高级第三次PTA作业(1)任何一个题目改为使用二级指针对指针数组进行操作。
int getindex(char *s)
{
char *a[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
char **p=&a[0];
//char *b='\0';
int i=0,result=-1;
for(i=0;i<7;i++)
{
if(strcmp(s,*(p+i))==0)
{
return i;
}
}
return result;
}
(3)用指针数组处理多个字符串有何优势?可以直接输入多个字符串给未初始化的指针数组吗?为什么?
使用指针数组处理多个字符串计较节省空间,因为每个字符串是单独存放的,不要求每个字符串占用同样的字节数,从而节省空间;不可以,未初始化数组,指针的指向的地址不确定,所以会出现一些错误;
2、将PTA作业的源代码使用git提交到托管平台上,要求给出上传成功截图和你的git地址。
git地址:
地址
上传截图:
3、点评3个同学的本周作业(在作业中给出被点评同学博客的链接),并邀请3名同学点评你的作业,无点评作业(你的作业未被3人点评)/或者没有回复同学或老师的点评都倒扣该题分数。
4、请用表格和折线图呈现你本周(4/9 8:00~4/23 8:00)的代码行数和所用时间、博客字数和所用时间。
表格:
折线图: