0.展示PTA总分(0----2)



1.本章学习总结(2分)

1.1 学习内容总结

关于知识点

  • 对于数组的话,要注意越界的问题;字符数组还需要注意,在while输入结束后,要有结束符。
  • 在做初始化操作时,可以用循环,当然,如果数据较少,可以直接用a[]={},如果要初始化为0,还可以定义为静态变量。
  • 有很多排序和查找的题目,需要判断什么时候能用什么方法,什么时候不能用。

在数组中查找数据

方法一:顺序查找法

  • 按顺序,从数组中的第一个元素开始查找
  • 举个例子:c07-一维数组7-5 有重复的数据I

    注:虽然引用了另外一个数组,但基本做法还是顺序查找(用到了哈希)

方法二:二分查找法

  • 比如按从小到大排序的数组,就是将数组对半分,然后比较中间的那个数,如果要找的那个数大于中间的那个数,则继续在右侧的那个数组里找,左侧的就不用再判断,如果小于中间数,则在左侧数组里找,重复比较中间数,直到找到或者数组全部比较完为止。这个方法只适用于按顺序排列的数组。
  • 举个例子:c07-一维数组7-8 二分查找法

在数组中插入数据

  • 首先应该把需要插入数据的位置空出来,从插入位置开始,每个数都要往后移动一个位置,然后再将数据插入预定的位置
  • 比如在一个数组a中的第三个数前插入数据1,假定a[100]=
定义a[100]存放数据,i为循环变量,n为插入的数
for i=9 To i=3
   a[i+1]=a[i];
end for
a[3]=n;

在数组中删除数据

方法一:

方法二:

  • 直接输出,在输出时更改条件
  • 比如:原数组有10个元素,假定删除了下标为2,3,5,7的数,然后输出条件如下:
for(i=0;i<10;i++)
{
   if(i==2||i==3||i==5||i==7)
   {
    continue;
   }
   else
   {
    printf("%d",a[i]);
   }
}

数组中目前学到的排序方法

选择排序法

  • 假定有数组a[n];在n个数中找到最小值,将它与a[0]互换,然后在0之后的n-1个数中找到最小值与a[1]互换,以此类推。简单来说,就是依次找到最小值并将它置于数组前列。
  • 举个例子:输入正整数n(1<n<=10),然后输入n个数,将它按顺序输出

冒泡排序法

哈希数组用法,目前学过哪些案例,举例展示。

哈希函数简单来说就是构造一个函数使得某个变量i有对应值。
例子如下:

1.2 本章学习体会

  • 每一次,在学习完新的东西的时候,才会发现,没有最难,只有更难。orz数组这一块,等于是在原来的基础上再增加了难度。需要考虑溢出的问题,字符数组还需要注意,while循环输入后得再加一个结束符。现在还不是很熟练,我偶尔还会犯一些低级错误。但是就像刚刚接触c语言的时候一样,我觉着,当我熟练后,应该就不会出现这些问题了。当然,还有很多其他的问题。最重要的是,数组题还不好找错,基本上是,一杯水,一包糖,一题代码写一天。还是希望,我能,更熟练地运用知识点吧。
  • 代码量:一维数组有493;二维数组有420。

2.PTA实验作业(7分)

2.1 c07-一维数组7-9 调查电视节目受欢迎程度

2.1.1 伪代码

定义变量n为参与投票的观众人数;response为观众所选择的项目;i用于循环计数;数组a[9]用于存放各个项目的票数
定义一个函数Statistic(int n)用于计算票数
输入n
引用Statistic函数
数组a[9]初始化为0
for 1 to n
   输入观众选择的项目
   if 输入的项目在范围内
      a[response]++
   end if
end for
for 1 to 8
   输出对应的项目和票数
end for

2.1.2 代码截图

2.1.3 造测试数据

输入数据 输出数据 说明
10 1 2 3 3 2 3 3 9 3 0 1 1 2 2 3 5 4 0 5 0 6 0 7 0 8 0 有非法输入9和0
8 2 3 4 1 2 3 2 4 1 0 2 3 3 2 4 2 5 0 6 0 7 0 8 0 正常输入

2.1.4 PTA提交列表及说明

说明:
这些个部分正确,都是段错误。原因是我没有考虑到观众输入的选择可能存在不合法的情况。每次的提交其实都跟原代码差不多。(不要问我为什么改来改去改不到点上我才不会告诉你我老是忘记段错误是个啥

  • 部分正确:第一次我的做法是先定义一个函数,然后把投票的值赋给a[i],再让另外一个函数b[a[i]]++。当然,因为👆的原因,我有了第一个段错误。
  • 部分正确:第二次,我突然觉着,为什么要定义两个数组,我觉着用数组来存放选择有点麻烦,然后就去掉了一个数组,把选择直接赋值给一个变量choose。当然,主要问题没解决,于是我有了第二个段错误。
  • 部分正确:第三次,我把定义的函数去掉了,直接将所以操作写在了主函数里。然后,就有了第三个段错误。
  • 部分正确:第四次,我发现我把输入语句写在了对数值的处理上,然后改了一下位置。第四个段错误。(此时,心态已崩
  • 部分正确:第五次,我开始有一点点意识到段错误究竟是什么意思了,然后我把a[9]改为了a[10],那会儿虽然觉着这样改没用,自己也觉着奇怪还是改了。然后,(⊙﹏⊙)第五个段错误。
  • 部分正确:第六次,害,我怀疑数组初始化不能用static,然后我改成了for循环。没有意外地,第六个段错误。
  • 部分正确:第七次,我好像是,不信邪,原样提交了。
  • 答案正确:最后是,认真比对了我和同学的代码的区别,终于,找到了问题!!然后我就重新写了一遍,连变量名都改了,类似于“这回我跟之前不一样总改过了吧”的心理。

2.2 2019-c08-二维数组7-4 求矩阵中的最大小值

2.2.1 数据处理

定义n和m为矩阵的行和列
定义函数FindTheMaximumAndMinimumValues(int n, int m)用于求最大值最小值及其下标,并输出
定义a[N][N]为输入的数组,max表示最大值,min存最小值,i和j用于循环计数
定义maxRow记录最大值下标,minRow记录最小值下标,maxCol记录最大值下标,minCol记录最小值下标
while 输入合法
引用函数FindTheMaximumAndMinimumValues(int n, int m)
for 0 to n
   for 0 to m
     输入数组的元素
     if 为数组的第一个元素
        对最大值最小值及其下标做初始化,赋0
     end if
     if 元素大于最大值
	max = a[i][j];
	maxRow = i;
	maxCol = j;
     end if
     if 元素等于最大值且这个元素所在的行的值比较小
	max = a[i][j];
	maxRow = i;
	maxCol = j;
     end if 
     if 元素小于最小值
	min = a[i][j];
	minRow = i;
	minCol = j;
     end if
   end for
end for
输出对应的最大值最小值及其下标

2.2.2 代码截图


2.2.3 造测试数据

注:由于数据太多,我就简要说明重点(n、m、最大最小值)

输入数据 输出数据 说明
3 4 最大 98 最小2 max=98 row=1 col=3 min=2 row=0 col=1 正常输入
4 5 最大两个重复的82 最小14 max=82 row=2 col=1 min=14 row=3 col=3 出现两个重复的最大值,另外一个最大值下标为(3,1)
2 4 最大 17 两个重复最小1 max=17 row=0 col=2 min=1 row=0 col=0 出现两个重复的最小值,另外一个下标(1,0)

2.2.4 PTA提交列表及说明

说明:这道题的话,其实是因为题目要求实现多组测试数据,然后我忽略了,再有就是要求最大值必须是行下标比较小的。

  • 答案错误:刚刚开始自己调试完,以为没有问题,结果出现了问题,就是↑的问题。
  • 答案错误:然后,我也不知道为什么,检查了之后,就觉着是不是格式出错,感觉代码没错,然后就在最后输出的地方,删掉了第二个输出的换行符,结果当然是,错误的。
  • 答案错误:这一次,认认真真检查了题目要求,发现它对重复的最大值有要求,就再加了一个if的条件句。但是没有实现多组测试数据。
  • 格式错误:这个呢,是加上了检查输入的while语句,大大多组测试数据的效果,但是之前去掉的换行符没有改回来。
  • 答案正确:加上换行符,就正确了。

2.3 2019-c08-二维数组7-7 螺旋方阵

2.3.1 数据处理

定义n来存矩阵的规格,
定义SpiralSquareMatrix(int n)来输出矩阵
定义i表示行,j表示列,number表示每次应该填的数,a[N][N]为矩阵,count用来记录输出的数的个数

对a[0][0]等变量做初始化处理。
while 1
   if count==n*n
      跳出循环
   end if
   while 数组左移一个位置,这个位置上的数为0
     j++;
     number++;
     a[i][j]=j;
     count++;
   end while
   while 数组下移一个位置,这个位置上的数为0
     做上述类似的递增及赋值
   end while
   while 数组右移一个位置,这个位置上的数为0
     做上述类似的递增及赋值
   end while
   while 数组上移一个位置,这个位置上的数为0
     做上述类似的递增及赋值
   end while
end while
输出a[N][N]   

2.3.2 代码截图



2.3.3 造测试数据

我突然间发现,我选的题,好像都对输入输出很不友好😭

输入数据 输出数据 说明
1 1 只有一个数据
10 输出的是从1到100的螺旋矩阵 其实这个已经超出了题目要求的范围,但我的代码还是可以实现的

2.3.4 PTA提交列表及说明

说明:我最开始,用while循环的时候其实用的是i来判断的,而不是i+1、i-1,但是后来发现这样子不行,它整个就直接混乱了,我才想着改成i+1,i-1的,因为我们要判断的是下一个,而不是这一个。(其实现在想想,当时可能是因为赋值和对下标的递增顺序没弄好吧)还有其他七七八八的问题,改来改去,我也不太记得我之前还该了些啥。

  • 编译错误:因为我漏打了一个)。
  • 运行超时:这个是,我死循环了。😭我就逐语句调试,很累,但是没办法,看不出来毛病然后发现,我忘记设的跳出循环的条件是(n-1)*(n-1),我受到了下标的迷惑😵
  • 答案正确:然后我就改了,然后就,正确啦。

3.阅读代码(-2--1分)

——来自ACM 题库题解大全

代码分析:

  • 功能:对一串字符进行分析,如果满足相隔n个字符的两个字符的结果彼此是不同的,则输出“字符串is surprising”,否则输出“字符串 is not surprising”。比如ABSHG的相邻组合有AB,BS,SH,HG,彼此不相同,且相隔1个字母的组合有AS,BH,SG,彼此也不相符...一直到相隔3个数都不相同,则ABSHG is surprising。

  • 思路大致应该是这样的:(说实在的,有些部分我看的还不是很懂,但是我觉着,大体思路我应该还是对的。)

    • 先用while实现多组数据的输入,if条件句使得输入遇*则终止程序;
    • 输入一个字符串s,然后把s中的每个字母拆分,d是表示相隔字母情况不同时字母间的下标差,然后从相邻开始组合,分配到数组a[][]中;
    • 用了顺序查找的方法,将不同组合相比较,如果发现有相同的情况,则跳出循环,输出not surprising;
    • 如果中途都没有跳出,则输出surprising
  • 优点:

    • 我觉着,他对组合的选取的方法是一个亮点。也就是对字符串的拆分。char **a,这个据说是一个二级指针,具体怎么用,我还不是很明白,它有点绕。总之就是活用指针和数组,然后取了字符串的某两个字母,组合起来,以便后面的判断。
    • 然后,还有一个是flag这个变量,我觉着用的挺好的,因为判断的时候用了多层循环,如果出现组合相同,那么一个break只能跳出一个循环,要想跳出多个循环,flag这个标志就显得很妙啦。(我记得好像还有一个goto语句,目前还没接触到,但是它对于代码的可读性有比较大的影响,虽然可以跳出多层循环,但阅读的时候,找的不是很方便,也不利于阅读者通晓思路)
    • 当然,代码整体比较规范,可读性较强,这个也是很重要的。(因为是题目,所以没有输入输出提示吧)