zoukankan      html  css  js  c++  java
  • C程序第三次作业

    6-1 输出月份英文名

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    第一步:将十二个月的名称分别赋值给一维数组指针,定义用于返回的数据类型。
    第二步:遍历数组,满足若n在1-12范围则将month第n-1行的首元素的地址赋给一开始定义的数据。
    第三步:返回变量的地址值。
    2.实验代码

    char *getmonth( int n ) {
       char *month[12] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
       char *pc = '';
       if(n>0 && n<=12){
       	pc = *(month+n-1);
       }
       return pc;
     } 
    

    3.本题调试过程碰到问题及解决办法
    错误点1:* pc未等于' ',导致当输入的月份不为1-12范围内时,则停止工作。

    解决方法:在注意到题目中“返回空指针NULL”后,将返回的指针型pc赋初值为''。
    错误点2:pc写成等于month+n-1
    解决方法:在单步调试时,查看了(month+n-1)的值,加上 * (month+n-1)后结果为正确,然而上课时并没有很注意老师说的这个知识点,所以有一点疑惑,在询问了二班的李伍壹同学后,并观看了老师的ppt并自己手动调试后,最终解决了问题: * (month+n-1)是第n-1行首元素的地址,** (month+n-1) 是第n-1行首元素的值。 李伍壹同学认真的程度真的很值得我去学习,同时自己也需要自我批评,课上一定要高度集中注意力。

    6-2 查找星期

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    第一步:将一个星期每天的英文分别赋值给一维数组指针,定义一个整型变量,赋初值为-1。
    第二步:遍历一维数组,用strmcp函数比较数组中每行元素与输入的字符串是否相同,若相同,则令此时的行数等于一开始定义的整型变量,且跳出循环。
    第三步:返回整型变量值。
    2.实验代码

    int getindex( char *s ) {
      int k=-1,i=0;
      int *day[7] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
      for(i=0;i<7;i++) {
      	if(strcmp(*(day+i),s)==0) {
      		k = i;
      		break;
    	  }
      }
      return k;
    } 
    

    3.本题调试过程碰到问题及解决办法
    错误点1:将strcmp((day+i),s)==0直接写成 *(day+i) == *s。
    解决方法:在第一题了解了之后,明白 * (day+i) 指的是第i行元素的首元素的地址,而 * s则表示的是首字母的值;且想起数组比较是否相等的话,必须要一个一个字母进行比较,只能用for循环或者是比较strcmp((day+i),s)的值,若为0则相等。
    strcmp函数:对两个字符串进行自左至右逐个字符相比,按ASCII值的大小比较,全部相等值则为0,出现不相等的字符,则以第一个不相同的字符比较为准,若前者大于后者,函数值为正整数,反之为负整数。

    6-3 计算最长的字符串长度

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    第一步:遍历s数组,运用strlen函计算出每行元素的长度。
    第二步:在for循环中进行比较,定义int型max,赋初值为0,当行元素的长度大于max,则将长度的值赋给max。
    第三步:返回max的值。
    (2)流程图

    2.实验代码

    int max_len( char *s[], int n ) {
       int max = 0,i=0,len;
       for(i=0;i<n;i++) {
       	len = strlen(*(s+i));
       	if(len > max) {
       		max = len;
    	   }
       }
       return max;
    	
    }
    

    3.本题调试过程碰到问题及解决办法

    6-4 指定位置输出字符串

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    第一步:先遍历s字符数组,找到与ch1相同时s的下标,并将下标值赋给一个整型变量,定义为j。
    第二步:在确定下标后,定义一个指针字符temp,将&s[i]赋给temp,后跳出循环。
    第三步:从上面的j开始,循环字符数组s,在循环中分情况,若s[i] != ch2,则输出s[i],反之则输出s[i]加换行,且返回temp。
    第四步:循环结束后,输出换行及返回temp。
    (2)流程图
    2.实验代码

    /*
    char *match( char *s, char ch1, char ch2 ) {
      int i,j=strlen(s),k = 0,m=0;
      char temp1[j+1];
      char temp2[j+1];
      for(i=0;s[i] != '';i++) {
      	if(s[i] == ch1) {
      		j = i;
      		break; 
    	  }
      }
     for(i=0;s[i] != '';i++) {
      if(s[i] == ch2) {
    		k = i;
    		break;
    	}
     }	
      if(k==0) {
      	k = strlen(s);
      } 
      for(i=j;i<=k;i++) {
      	temp1[m] = s[i];
      	m++;
      }
      printf("%s
    ",temp1);
      m=0;
      for(i=j;s[i] != '';i++) {
      	temp2[m] = s[i];
      	m++; 
      }
      return temp2; 
    } 
    */
    char *match( char *s, char ch1, char ch2 ) {
      int i,j=strlen(s),k = 0,m=0;
      char *temp;
      for(i=0;s[i] != '';i++) {
      	if(s[i] == ch1) {
      		temp = &s[i];
      		j = i;
      		break; 
    	  }
      }
     for(i=j;s[i] != '';i++) {
      if(s[i] != ch2) {
    		printf("%c",s[i]);
    	} else {
    		printf("%c
    ",s[i]);
    		return temp; 
    	}
     }
     printf("
    ");
     return temp; 	
    }
    

    3.本题调试过程碰到问题及解决办法
    错误点1:在dev中运行正确,却在pta全部答案错误。
    解决方法:将temp2字符数组改成指针变量后,则为部分正确,猜测为pta中此题不支持字符数组的形式,最后将temp1舍去,按照满足条件则输出对应单个字符的思路重新构思代码,最后正确。

    一道编程题:

    #include <stdio.h>
    
    int main ()
    {
      	int m=20,n=970;
      	//int型变量范围为-32768-32767,int n[10000]是不行的,因为这样定义的数组用的是栈
    	//内存,系统默认值为最大1Mb,一个int型占4字节这样最大可以申请1024*1024/4=264144
    	//个,如果考虑到系统自身的占用最大值为25000个。
    	int *p = (int *)malloc((m*n) *sizeof(int));
    	int *q = (int *)malloc((m*n) *sizeof(int));//用的是堆内存,只要内存中有那么多的连续空间就可以。 
    	int i=0,j;
    	for(i=0;i<(m*n);i++) {
    		p[i] = i+1;
    	}
    	for(i=0;i<(m*n);i++) {
    		for(j = i+1;j<=(m*n);j++) {
    			if(p[i] !=1&&p[j] != 1) {
    				if(p[j]%p[i] ==0) {
    					p[j] = 1;
    				}
    			}
    		}
    	}
    	j=0;
    	for(i=0;i<(m*n);i++) {
    		if(p[i] != 1) {
    			printf(" %d",p[i]);
    			j++;
    		} 
    		if(j == 5) {
    			printf("
    ");
    			j=0;
    		}
    	}
    } 
    

    然而上面的代码是存在bug的,当数字过大时,最终系统会一直加载不出来,例:当输入的数字是20970时,最后答案是可以的,然而变成201970时则不可以。而在老师讲授完此课程的时候,自己又将自己的代码进行了一次修改,最后答案可以输出。

    #include <stdio.h>
    #define N 201
    #define M 970
    int a[N][M]; 
    int del(int s[N][M],int x) {
    	int n,m;
    	for(n=0;n<N;n++) {
    	 for(m=1;m<M;m++) {
    	 	if(s[n][m]==0) continue;
    	 	if(s[n][m]!=x && (s[n][m]%x)==0) {
    	 		s[n][m]=0;
    		 }
    	 } 
     }
     return 0;
    }
    int main()
    {
    	int n=0,m=0,number=1,i=0;
    	for(n=0;n<N;n++) {
    		for(m=0;m<M;m++) {
    			a[n][m]=number++;
    		}
    	}
    	for(n=0;n<N;n++) {
    		for(m=1;m<M;m++) {
    			if(a[n][m]!=0) {
    				 del(a,a[n][m]);
    	
    			}
    		}
    	}
    	for(n=0;n<N;n++) {
    	    for(m=1;m<M;m++) {
    	    	if(a[n][m]!=0) {
    	    		printf(" %d",a[n][m]);
    	    		i++;
    			}
    			if(i==5) {
    				printf("
    ");
    				i=0;
    			}
    		}
    	}
    	return 0;
      }  
    

    6-1 奇数值结点链表

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    第一步:在readlist函数中,将输入的值存储在链表里,且用while循环时条件为输入的值不为-1,在while循环内对p进行动态分配内存,切记在完全输入以后,末尾结点的next为空,最后返回链表的头结点。
    第二步:在getodd函数中,根据题目要求的条件对链表结点中date的值进行分类判断,将数值为偶数的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.本题调试过程碰到问题及解决办法
    错误点1:未在readList子函数中加上tail->next = p.
    解决方法:在dev中运行没有结果且调试会出错,在多次单步运行后发现若最后不加tail->next = p,最后的p->next不会为空,传下去则会造成getodd函数中的p值在最后仍不为空,最后造成系统的报错。


    错误点2:在getodd函数中while的条件写成p->next!=NULL。
    解决方法:在单步调试后发现,若写成p->next!=NULL,最后一个结点会不满足while的条件,直接跳过循环,进入下一步,最终导致答案错误。

    6-2 学生成绩链表处理

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    第一步:在createlist函数中将输入的学号,姓名和分数存储到链表中,while循环的条件为学号不为0,因当学号为0时不需要输入姓名及分数,即结束,因此需明确必须在判断学号不为0的情况下才可以输入姓名和成绩,返回链表的头结点。
    第二步:在deletelist函数中遍历链表的结点,若结点中的分数小于规定的值则释放此结点的内存,需注意若最终结点全被释放完内存,即返回的头结点为空的情况。
    第三步:将判断后链表的头结点返回主函数。
    (2)流程图

    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;
      } else {
      	free(L);
       }
       L=L->next;
      }
      if(head1==NULL) {
      	return NULL; 
      } else {
      	tail1->next =NULL;
      }
      return head1;
    } 
    

    3.本题调试过程碰到问题及解决办法
    错误点1:在判断输入的成绩小于规定值后,并没有将此时的结点内存释放。
    解决方法:在看了PTA调试错误的类型后,重新仔细思考了自己的代码结合老师上课所讲的用free可以释放内存的知识点,最终解决问题。

    错误点2:在函数deletelist中while循环的结束后,忘记加tail1->next =NULL,导致第一个测试点答案错误。
    解决方法:在调试及各种值的带入都找不出错误原因后,仔细思考了此测试点没错的同学的代码,最终发现问题。

    6-3 链表拼接

    PTA提交列表:

    1.设计思路
    (1)主要描述题目算法
    (2)流程图
    2.实验代码

    struct ListNode *mergelists(struct ListNode *list1, struct ListNode *list2) {
       struct ListNode *p1=list1;
    	 int length=0;
    	 int array[100];
    	 for(p1=list1;p1!=NULL;p1=p1->next) {
    	 	array[length] = p1->data;
    	 	 length++;
    	 } 
    	 p1=list2;
    	 for(;p1!=NULL;p1=p1->next) {
    	 	array[length] = p1->data;
    	 	 length++;
    	 } 
    	 int i,j,t;
    	 for(i=0;i<length-1;i++) {
    	 	for(j=i+1;j<length;j++) {
    	 		if(array[j]<array[i]) {
    	 	      t =array[j];
    			  array[j]=array[i];
    			  array[i] = t;
    			 }
    		 }
    	 }
    	 struct ListNode *q,*head1 = NULL,*tail1=NULL;
    	 i=0;
    	 while(i<length) {
    	 	q = (struct ListNode *)malloc(sizeof(struct ListNode));
    	 	q->data = array[i];
    		 if(head1 == NULL) {
    			head1 = q;
    		} else {
    			tail1->next = q;
    		}
    		 tail1 = q; 
    		 tail1->next = NULL;
    		 i++; 
      }
    	 return head1;
    }  
    

    3.本题调试过程碰到问题及解决办法
    遇到的问题1:将函数最后的tail1->next=q与tail1=q位置放反,导致系统崩坏。
    解决方法:单步调试后发现顺序的问题,最后改正。

    遇到的问题:一开始自己的思路为,新建一个链表,将之前两个链表的值统合到此一个列表中,在定义一个一维数组,最后将新建链表中date的值赋给此一维数组,然后用选择法进行数组元素的排序,最终将排好序的数组赋值给一个新的链表,最终返回新的链表头结点
    ,但在pta中会导致最后结果全为段错误,即超出内存。
    最后在网上搜寻答案后,简化代码,即直接将合并的两个链表的值直接赋给一维数组,然后进行选择法排序,将排好的值赋给新建链表即可,最后返回新建列表的头结点。

    struct ListNode *p1=list1,*head1=NULL,*tail1=NULL;
       for(;p1!=NULL;p1=p1->next) {
       	if(head1==NULL) {
       		head1 = p1;
    	   } else {
    	   	tail1->next=p1;
    	   }
    
    	   tail1 = p1;
         }
         p1 = list2;
         for(;p1!=NULL;p1=p1->next) {
         	 tail1->next = p1;
         	 tail1 = p1;
    	 }
    	 tail1->next=NULL;
    	 int length=0;
    	 int array[100];
    	 for(p1=head1;p1!=NULL;p1=p1->next) {
    	 	array[length] = p1->data;
    	 	 length++;
    	 } 
    

    学习总结和进度

    1、总结两周里所学的知识点,回答下列问题?
    1)如何理解指针数组,它与指针、数组有何关系?为何可以用二级指针对指针数组进行操作?
    答:指针数组是存放指针的数组,即是数组的形式,但数组中的元素为指针,而指针又叫指针变量是存放指针的变量,即存放地址的变量;用二级指针指向指针数组的第一个元素,此时二级指针中存放指针数组第一个元素的地址,若定义二级指针为int ** p,指针数组为 int * num[]里面存储着int a[]的地址,则p表示num[0]的值,指向a[0],值为a[0]的地址, p+i指向数组元素a[i],且 * (*p+i)表示数组元素a[i]。
    2)将C高级第三次PTA作业(1)任何一个题目改为使用二级指针对指针数组进行操作。
    6-1 输出月份英文名改为使用二级指针对指针数组进行操作,代码如下:

    char *getmonth( int n ) {
       char *month[12] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
       char **p = &month[0]; 
       char *pc = '';//*pc未等于'' 
       if(n>0 && n<=12){//n写成>=0 
       	pc = *(p+n-1);//pc写成等于month+n-1 
       }
       return pc;
     }
    

    3)用指针数组处理多个字符串有何优势?可以直接输入多个字符串给未初始化的指针数组吗?为什么?
    答:如果用二维数组保存多个字符串比较浪费内存空间,每个字符串必须要占用同样的字节数,从而浪费了一定的空间,而指针数组的话,可以通过初始化字符串由编译器自动决定数组的长度,从而节约内存;不可以,因为若未将指针初始化的话,指针会指向一个不确定的地址,而此地址中有可能存储着有用的数据,会破坏系统的正常工作情况。
    2、将PTA作业的源代码使用git提交到托管平台上,要求给出上传成功截图和你的git地址。







    git地址:(https://git.coding.net/exo07/disizhouzuoye.git)
    3、点评3个同学的本周作业(在作业中给出被点评同学博客的链接),并邀请3名同学点评你的作业
    史泽文:(http://www.cnblogs.com/shilcz/p/8906128.html)
    高立彬:(http://www.cnblogs.com/gao628526/p/8781936.html)
    董欣:(http://www.cnblogs.com/dx2017/p/8781858.html)
    4、请用表格和折线图呈现你本周(4/9 8:00~4/23 8:00)的代码行数和所用时间、博客字数和所用时间

  • 相关阅读:
    团队博客创建
    筼筜湖美景
    作业11-网络
    作业11-多线程
    多线程-冲突与同步代码
    Java第12次实验提纲(JSP简单入门)
    作业-JSP简单入门
    Java Web参考资料
    面向对象设计大作业迭代任务
    在码云(gitee)上展开程序类课程教学
  • 原文地址:https://www.cnblogs.com/exo123/p/8798720.html
Copyright © 2011-2022 走看看