一、PTA实验作业(5分)
题目1:6-8 使用函数实现字符串部分复制
1. 本题PTA提交列表(要提交列表,不是结果)
2. 设计思路(伪代码或流程图)
- 伪代码:
函数定义void strmcpy( char *t, int m, char *s ) 定义i,n两个变量 for i=0 to *(t+i)!='\0' i++ end n=i //用循环记录字符的长度 判断输入的m是否小于长度n,若是进入循环{} for i=0 to *(t+m+i-1)!='\0' i++ { *(s+i)=*(t+m+i-1); end } *(s+i)='\0'; } 若m大于n则 *s='\0';
- 流程图:
3.代码截图(注意,截图,截图,截图。不要粘贴博客上。不用用···语法去渲染)
4.本题调试过程碰到问题及PTA提交列表情况说明。
- 首先我遇到的情况是m=n时我没有将它考虑进去,我直接判断了m<n的情况,如上图所示。
- 还有就是我在判断从第m为开始输出时我是直接p+m+i,其实是要p+m+i-1,因为数组是从0开始的。
题目2:6-9 求子串在母串中最后一次出现的地址
1. 本题PTA提交列表(要提交列表,不是结果)
2. 设计思路(伪代码或流程图)
定义函数char *fun (char *s, char *t ){ 定义n,i,j,flag=0,l 5个变量 for i=0 to *(s+l)!='\0' { for(i=l,j=0;*(s+i)==*(t+j);i++,j++) { 如果子串到达结束符位置即*(t+j+1)=='\0 ' { flag=1; n=l; } //flag 做为出现子串的标志 end} end } 如果没有子串即flag==0 返回 NULL; 否则 返回 s+n; }
3.代码截图(注意,截图,截图,截图。不要粘贴博客上。不用用···语法去渲染)
v
4.本题调试过程碰到问题及PTA提交列表情况说明
- 这道题刚开始我竟然忘记写第一个循环了,导致一直错误,因为在课上老师讲过这道题所以
我就翻看了以前的题目改了过来,还有编译错误的原因是我在写*t+j+1时忘记加括号了这是
一个失误点。
题目3:6-10 字符串串动变化
1. 本题PTA提交列表(要提交列表,不是结果)
2. 设计思路(伪代码或流程图)
定义函数void * fun(char *p){ 定义变量 int n,i max=*p; //存储第一个字符 for i=1 to *(p+i)!='\0'{ 比较每一个字符找出其中最大值放入max中 end} x=*(p+n);//先储存第n个数防止移位后改变 for(i=n;i>0;i--){ *(p+i)=*(p+i-1);//将字符移到后一位 end} *p=x //再将原先储存的内容赋值于第一位
3.代码截图(注意,截图,截图,截图。不要粘贴博客上。不用用···语法去渲染)
4.本题调试过程碰到问题及PTA提交列表情况说明。
- 这道题主要错在我移位之后导致数组第n个字符已经改变,而我没有给他先保存下来
导致赋给数组第一个时是改变后的值,导致错误。
二、截图本周题目集的PTA最后排名。(2分)
三、阅读代码(2分)
题目1:
优秀解答:
#include <stdio.h> void main(){ long int digit[101]; //存放结果的数组,0号元素放整数部分,其余放小数部分 long int remainder[101]; //存放余数 int state=0; //是否是循环小数,默认不是 long int repetendstart=0; //循环节的开始位置和结束位置 long int n,d; //输入的分子和分母 int i; printf("input N/D:"); scanf("%d/%d",&n,&d); //输入分子和分母 digit[0]=n/d; remainder[0]=n%d; //求出第一个余数 i=0; while(remainder[i] && !state && i<100){ //求小数部分 i++; //i记录了求了多少位小数 digit[i]=remainder[i-1]*10/d; //求出一位小数 remainder[i]=remainder[i-1]*10%d; //求余数即下一次的被除数 for(int j=0;j<i;j++){ //判断是否出现循环节 if(remainder[j]==remainder[i]){//如果出现循环节则记下节开始的位置 repetendstart=j+1; state=1; //置是循环小数状态 break; } } } //以下是打印部分 printf("%d",digit[0]); //打印整数部分 if(remainder[0]!=0) printf("."); //如有小数则打印小数点 for(int j=1;j<=i;j++){ //打印小数部分 if(j==repetendstart) printf("("); printf("%d",digit[j]); } if(state) printf(")"); printf("\n"); }
- 这题难点在于如何求出循环的小数部分,如何在输出时用括号括起来。
- 我找到的方法是用两个数组,一个储存整数部分,一个储存小数部分,因为只有分开去才可以判断出循环的部分,
在求小数的部分时加入内循环判断是否出现循环的小数,就是加入一个循环,而难点也在这里,我看了好久,主要原
理是在内循环中找到一个位置使其与现在的被除数相同,然后在加上1就是循环小数开始的位置,记录下这个位置,
直接退出循环,不仅求出了循环体小数的位置,且可以直接退出,执行输出。
题目2:
优秀解答:
void CountOff( int n, int m, int out[] ){ int i=0,j=0,k=0,cnt=0,a[MAXN]; for(i=0;i<n;i++) //先对应的人的报数赋值 a[i] = i+1; i=0; while(cnt < n){ if(a[i]!=0) k++; //记录报数的位置 if(k==m){ j++; out[i]=j; //第几次退出 k=0; //重新开始 cnt++; //剩余的人 a[i]=0; //使其为0跳过 } i++; if(i==n)//遇到最后一位从0开始 i=0; } }
- 这道题刚开始连题目都看不懂,我以为是输出退出的第几个人,但是题目却是4 10 1 7 5 2 11 9 3 6 8,我还以为是
题目错了,后来才知道是输出退出的是第几次。 - 首先,是先把报数的人赋值为1~n,k记录报数的数值,直到报到m,然后out[i]=j,j是指第几次输出,在重新赋值,
知道最后一个数字都退出。这里用2个数组直接就作出了,一个用来判断报数的人,一个来记录退出的是第几次。
四、本周学习总结(1分)
1.自己总结本周学习内容。
- 学会了指针在函数中的传参,同时也学会了用指针来指向数组,如
*(a+i)
- 同时也知道
*a++
是错的*a+i
必需加上括号。 - 还有就是用二维数组来存储多个字符,如输入多个字符串可以定义char a[][],行输入第几个数组,列输入字符串。
- 另外指针的赋初值,如果忘记给指针赋值的话就会导致程序崩溃。
- 学会了string的库函数的用法,如字符的连接strcat,字符串的复制strcpy等等
2.罗列本周一些错题。
- 这题就是我用
*n++
导致错误。
- 这题要求输出的是整数的值,答案应该是sum=sum+*s-'0'而我却忘记减0了。
来源:https://www.cnblogs.com/czx153/p/8030409.html