C语言博客作业04--数组

0.展示PTA总分

  • 一维数组
  • 二维数组
  • 字符数组

1.本章学习总结

1.1 学习内容总结

  • 数组的查找通常是用下标,也可以用新学的指针来查找。
    使用下标的话,可以使用顺序查找法,即从头到尾扫描
    也可以用二分查找法,逐渐缩小查找范围的方式

  • 数组中如何插入数据

  • 伪代码:
    定义insertPosition,用来表示插入的数据
    要插入的数据为x
    第一个for循环:让x与数组中每个数比较,比它大时insertPosition改变为该数组后一位的下标
    第二个for循环:让数组从后往前依次得到它前面的数的值,达到后移一位的效果
    最后将该插入的x放入insertPosition下标的对应的位置

  • 删除数据的做法
    1.重构数组
    即在原来的数组上进行修改
    这样做的缺点是会破坏原来的数组
    一维数组的数据元素删除(7-6)比较简单,因为直接对应下标,直接左移数组即可
    代码截图:
    若是要对某个数据进行删除,则需要先扫描到该数据对应的下标并传入deleteIndex
    2.构建新数组存放
    这个做法就要好许多,除非题目有特殊要求只能在原数组上修改
    因为这个做法的优点是可以保留原数组,只要将除了要删除的数据存入新构建的数组中即可
    不过在做连续删除的时候会不如第一种做法

  • 目前学到的排序方法主要有两种,一种是冒泡排序法,一种是选择排序法
    选择排序法的思路是:将第一个数a[0]与后面所有的数比较,找到最小或者最大的数放在第一个数a[0]的位置;第二次从第二个数a[1]开始,将找到的次大或次小的数放在a[1],以此类推
    冒泡排序法的思路是:将a[0]与a[1]比较,小的放前面,大的放后面,再将a[1]与a[2]比较,以此类推,直到把最大的数放在最后,然后选出第二大的数,以此类推
    两种做法各有优缺点

  • 数组做枚举用法
    课堂派上做的进制转换的题(找不到在哪就没放图)

  • 哈希数组
    可用于统计输入的某个数据的次数
    pta上一维数组7-9调查电视节目的受欢迎程度就可以用这种做法

    其中还有一维数组7-5有重复数据这题

    这里利用的是将数据输进新数组中唯一的位置上,扫描当前数据与新数组中对应位置的数据是否相等并判断的做法

1.2本章学习体会

  • 课堂派做题的时候,经常会遇到一些书上没有的知识,老师在课堂上有时也没有讲到
  • 1269行,未达标

2.PTA实验作业

2.1一维数组7-5有重复数据

2.1.1伪代码

定义一个常量N 100001(足够大)
定义a[N]储存N个数
定义c[N]储存N个数,并赋予全部初值0
定义flag记录是否重复,赋值为0
输入要输入的个数n
for int i=0 to i<n
    输入a[i]
end for
for i=0 to n-1
    if(a[i] == c[a[i]]) then
        flag=1
        break
    end if
    c[a[i]] = a[i];
end for
if(flag==1) then
    printf("YES")
else
    printf("NO")
end if
  • 思路:把第一次出现的数存入c[N]当中,数据是多少就存放在哪个位置,当有相同数据进入时,如果c[N]中已经有这个数,那么flag=1,并输出YES,完全没有重复,flag不变,为0,输出NO
  • 这题其实是哈希数组的应用

2.1.2代码截图

2.1.3造测试数据(太大的不方便造,这里只展示部分小数据)

输入数据 输出数据 长长的标题3
5
1 2 3 1 4
YES 正常数据
5
1 5 6 8 9
NO 正常数据
1
5
NO 单个数据

2.1.4PTA提交列表及说明

1-3部分正确:前两个测试点正确,最后一个测试点超时,即老师在超新星平台上提到的当N最大时循环次数过多的超时问题,这三次错误是我在循环嵌套的基础上进行修改
4.答案错误:完全推翻重打,利用哈希数组,改成了单层循环,什么都加了,就是忘记打上两个printf...
5.答案正确:加上两个printf后,因为是单层循环,测试点三不会超时就过了

2.2二维数组7-6阅览室

2.2.1伪代码

定义常量M2000
定义天数n
定义一天内借书的次数count=0
定义天数计数count_n=0//当该数等于天数n时结束循环
定义flag//用于忽略无效记录
定义小时hour,定义分钟minute
定义一天总时间time
定义一天平均时间AVerageTime=0
定义operation//存放当前操作是S或E
定义数组a[M][2]//第一列存储书名,第二列存储时间(统一分钟)
定义数组b[M]
定义数组c[M],初值全为0
while (count_n != n)
    输入a[i][0],operation,hour,minute
    a[i][1]=hour换算成分钟加minute
    if (operation == 'S' && a[i][0] != 0) then
        flag++;//每次输入增加1
	count++;
	b[a[i][0]] = a[i][1];
	c[a[i][0]] = 1;
    end if
    if (operation == 'E' && flag != 0 && a[i][0] != 0 && c[a[i][0]] != 0) then
        flag--;//每次有效输入(即不重复)减少1
	b[0] = a[i][1];
	time += b[0] - b[a[i][0]];
	c[a[i][0]] = 0;//防止同一书名的重复输入
    end if
    if (a[i][0] == 0) then
        if (flag != 0) then//当flag不等于0时,说明输入的S和E不对等
            清除多余的S输入导致的count++
        end if
        if(count != 0) then
            计算一天平均阅读时间
        else
            平均阅读时间为0
        end if
        输出一天借书的次数count和平均阅读时间AverageTime
        count = 0;
	count_n++;//累计输入n次0,即n天,就结束循环
	time = 0;
	flag = 0;
    end if
end while

2.2.2代码截图

2.2.3造测试数据

2.2.4PTA提交

1.部分正确:没处理无效的S或E的重复输入,导致程序出错
2.部分正确:测试数据中的第二天无输入处理不当,导致结果为1,0,实际应为0,0,原因是没有对count进行清零
3.编译错误:复制代码时不小心把其中一个分号改成了中文的
4.答案正确:详细修改并改好细节后正确

2.3字符数组7-2IP地址转换

2.3.1伪代码

定义数组base[33]
定义四个ip1,2,3,4,都=0
输入32位二进制字符串
for int i=0 to 32
    if(i <= 7) then
        每个数乘2的n次方,n为该数的位数-1(每8个数一组,第一个数为8位)
        ip1 += (base2[i] - '0') * pow(2, 7 - i);
    else if(i > 7 && i <= 15)
        ip2 += (base2[i] - '0') * pow(2, 15 - i);
    else if(i > 15 && i <= 23)
        ip3 += (base2[i] - '0') * pow(2, 23 - i);
    else
        ip4 += (base2[i] - '0') * pow(2, 31 - i);
    end if
end for
输出ip地址

2.3.2代码截图

2.3.3造测试数据

输入数据 输出数据 说明
11001100100101000001010101110010 204.148.21.114 测试数据
全为1 255.255.255.255 极限数据
全为0 0.0.0.0 极限数据

2.3.4PTA提交列表及说明

1.部分正确:base定义为32导致输入全为1时最后一个ip会变成254
2.答案正确:修改了base为33,多给了个位置,修正错误

3.阅读代码

  • 代码功能:把26个字母按顺时针顺序输出,如果不够,再次从A开始(不限于正方形矩阵)
  • 优点:充分利用数组的功能,结构工整,合适的换行和注释使代码不会拥挤,看起来很舒适
posted @ 2019-11-17 21:44  林盛泓  阅读(333)  评论(1编辑  收藏  举报