C语言博客作业04--数组
1.本章学习总结
1.1 思维导图
1.2 本章学习体会及代码量学习体会
1.2.1 学习体会
- 这几周初步学习了几种数组:一维数组、二维数组和字符数组。
- 数组可以存储数值,可以将多个相同类型的变量集合起来,方便使用。
- 相对之前的学习来说,更需要深入理解题目,才能找到思路。
- 数组很重要,关系到后面指针和数构的学习,因此基础更要打好。
1.2.2 代码累计
2.PTA总分(2分)
2.1截图PTA三次题目集:一维数组、二维数组和字符数组共3次题目集的排名得分
2.2 我的总分:
一维数组:183分;
二维数组:105分;
字符数组:150分;
总分:438分
3.PTA实验作业(6分)
在一维数组、二维数组和字符数组每个题目集选1题你觉得完成难度最大题目介绍。每题2分,做如下内容:
3.1 PTA题目1
在一大堆数据中找出重复的是一件经常要做的事情。现在,我们要处理许多整数,在这些整数中,可能存在重复的数据。
你要写一个程序来做这件事情,读入数据,检查是否有重复的数据。如果有,输出“YES”这三个字母;如果没有,则输出“NO”。
3.1.1 算法分析
定义 hash[10000]={0},
for i=0 to n
输入number;
hash[number]++;
if hash[number]==2
输出"NO"
if 所有hash[number]!=2
输出"YES"
3.1.2 代码截图
3.1.3 PTA提交列表及说明
开始时是用for循环的嵌套进行查找,认为这道题非常简单,但是后来测试时发现最以后一个测试点怎么也过不去,总是显示运行超时,应该是数组太大,循环需要的时间很长。于是听完课之后才知道了哈希查找法,非常有用,对此印象极为深刻。也学到了一种新的数组运用方法。
3.2 PTA题目2
天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下S键,程序开始计时;当读者还书时,管理员输入书号并按下E键,程序结束计时。书号为不超过1000的正整数。当管理员将0作为书号输入时,表示一天工作结束,你的程序应输出当天的读者借书次数和平均阅读时间。
注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有S没有E,或者只有E没有S的纪录,系统应能自动忽略这种无效纪录。另外,题目保证书号是书的唯一标识,同一本书在任何时间区间内只可能被一位读者借阅
3.2.1 算法分析
输入天数N
for i=1 to N
输入书号num键值ch和时间hour,mintue
if ch'S'且num!=0
a[num]=hour*60+minute;
flag[num]=1;
else if ch'E'且num!=0且flag[num]1
time=hour*60+minute-a[num];
a[num]=flag[num]=0;
sumtime+=time;
k++;
while num!=0
if k0 输出"0 0"
else 输出k,sumtime的值
初始化数组a[100]全为0; k=0; sumtime=0;
3.2.2 代码
3.2.3 PTA提交列表及说明
开始拿到题目时非常抓瞎,完全不知道从哪下手,输入输出包括判断什么时候读入E和S的条件一团乱麻。
数组的题目如果思路不明确是非常令人头昏的,所以导致了我一开始提交的全面失败。
后来静下心来思考,一个功能一个功能地写好完善,一点一点地写一个模块测试一个模块,一遍又一遍的提交,才通过了测试。
3.3 PTA题目3
一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下:
首先对前17位数字加权求和,权重分配为:{7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};然后将计算的和对11取模得到值Z;最后按照以下关系对应Z值与校验码M的值:
Z:0 1 2 3 4 5 6 7 8 9 10
M:1 0 X 9 8 7 6 5 4 3 2
现在给定一些身份证号码,请你验证校验码的有效性,并输出有问题的号码。
3.3.1 算法分析
输入要检验的身份证号码个数N
for i=1 to N
sum=0;
输入字符串并存入数组a
for j=0 to 17
if(a[j]>'9'||a[j]<'0')
flag=2;
break;
sum=(a[0]-'0')7+(a[1]-'0')9+(a[2]-'0')10+(a[3]-'0')5+(a[4]-'0')8+(a[5]-'0')4+(a[6]-'0')2+(a[7]-'0')1+(a[8]-'0')6+(a[9]-'0')3+(a[10]-'0')7+(a[11]-'0')9+(a[12]-'0')10+(a[13]-'0')5+(a[14]-'0')8+(a[15]-'0')4+(a[16]-'0')*2;
num=sum%11;
switch (num)
{
case 0:num='1';break;
case 1:num='0';break;
case 2:num='X';break;
case 3:num='9';break;
case 4:num='8';break;
case 5:num='7';break;
case 6:num='6';break;
case 7:num='5';break;
case 8:num='4';break;
case 9:num='3';break;
case 10:num='2';break;
}
if num!=a[17]||flag2
输出字符串并换行
flag=1;
if flag0&&i==N
输出"All passed"
3.3.2 代码
3.3.3 PTA提交列表及说明
开始时没有注意到X,运用了一维数组,然后后面很乱,之后想到用字符数组时,因为采用gets()输入,导致回车键没有被键入,又影响了下一个身份证号码的验证,后来采用了scanf("%s",str)输入,解决了这个问题。看来这些不同的输入输出方式也有着微妙的差别,需要认真去学习观察a。
4.代码互评
4.1 代码截图
[我的代码]
[吴沂聪的代码]
4.2 二者的不同
- 从整体来看我的代码量和吴沂聪的差的不是很多,他的要比我少一点,因为我的switch语句比较占行数= =。
- 吴沂聪同学运用了三个数组进行运算,并且运用到了二维字符数组。
而我只运用了一个一维的数组。
就这一方面来说,我觉得我的定义较为简便,但是他的定义两个一维数组值得学习,这样我在加权求和时就不用写很长一列公式了。 - 他在字符串输入一行上加了一行getchar();目的是为了防止第一次输入N时回车键的干扰。
而我直接在输入一栏中将回车键加入了格式中,也同样不影响字符串的输入。
我们各有特点,他的方法是我没有想到的,值得学习。 - 他的加权求和在最后,并且前面运用较多循环语句,来判断数据合法性。
我的加权求和在判断数据合法性之前,先求和再判断,没有那么多for循环语句。
各有优劣,我觉得都可以互相借鉴,以期达到更好的效果。