C博客做业04--数组

1. 本章学习总结

1.1 思惟导图

1.2 本章学习体会及代码量学习体会

1.2.1 学习体会

这几周学习了数组,一维数组,二维数组,字符数组,前一个题集还没作完,后一个题集就又发布了,当场去世,可能由于题目难度也在增长,而后有些懒,题目一直放着没有好好去作,都是等老师讲完有了思路,再根据老师的思路把代码打一遍。这一点自我反省一下。学习了数组,而且学了几种排序方法,以前的一些题目也能够改用数组的方法来作。感受数组有些题目有思路作起来,也有点懵懵的,不能一遍过,都须要调试一下才知道本身的问题出在哪。数组这块的内容仍是很重要的,因此我应该要把知识盲区都弄懂,而且累计一些作题思路。并且题集也不能一拖再拖了,遇到难题也不该该是躲避了,但愿在接下去的时间里,我能够把它们全解决掉。

1.2.2 代码累计

2. PTA总分

2.1 截图PTA中数组题目集的排名得分



2.2 个人总分:390

一维数组:175
二维数组:105
字符数组:110

3. PTA实验做业

3.1 PTA题目1

数组循环左移 
本题要求实现一个对数组进行循环左移的简单函数:
一个数组a中存有n(>0)个整数,在不容许使用另外数组的前提下,将每一个整数循环向左移m(≥0)个位置

3.1.1 算法分析

定义i,j,n,m,temp
输入n,m
输入n个数存入数组a
for i=0 to m do
    temp=a[0]
    for j=0 to n-1 do
        a[j]=a[j+1]
    a[n-1]=temp
    end for
end for
按照要求格式输出

3.1.2 代码截图

#include<stdio.h>
int main()
{
    int n,m,i,j,temp;
    scanf("%d%d",&n,&m);
    int a[n];
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<m;i++)                 //左移次数
    {
        temp=a[0];                //先用temp储存a[0]
        for(j=0;j<n-1;j++)
            a[j]=a[j+1];                //各数往前移
      a[n-1]=temp;                  //将a[0]放到最后一位
    }
    for(i=0;i<n;i++)
    {
        if(i<n-1)
            printf("%d ",a[i]);
        else
            printf("%d",a[i]);
    }
    return 0;
}

3.1.3 PTA提交列表及说明

Q1:刚开始作,挺有思路的可是感受代码质量不好,并且有一两个点一直过不了
A1:后来老师在课上讲了这题,瞬间有种顿悟的感受,好方法就要累积下来

3.2 PTA题目2

找鞍点 
一个矩阵元素的“鞍点”是指该位置上的元素值在该行上最大、在该列上最小。

3.2.1 算法分析

定义i,j,k,n,temp,flag,count=0
输入n
输入n行n列的二维数组
用两层for循环遍历这个二维数组
    初始化flag,temp为0
    for k=0 to n do
        if a[i][j]<a[i][k] then
            flag=1
        end if
    end for
    for k=0 to n do
        if a[i][j]>a[k][j] then 
            temp=1
        end if
    end for
    if flag==0 && temp==0
        count++
        输出 i j
    end if 
end for
if count==0 then
    输出 NONE

3.2.2 代码

改前算法

#include<stdio.h>
int main()
{
  int i,j,k,temp;
  int flag=0,count=0;
  int n;
  scanf("%d",&n);
  int a[n][n];
  for(i=0;i<n;i++)
  {
    for(j=0;j<n;j++)
    {
      scanf("%d",&a[i][j]);
    }
  }
  int max;
  for(i=0;i<n;i++)
  {
    flag=0;
    max=a[i][0];
    for(j=0;j<n;j++)
    {
      if(a[i][j]>max)                 //找出行中最大值
      {
        max=a[i][j];
        temp=j;
      }
    }
    for(k=0;k<n;k++)
    {
      if(a[k][temp]<max)         //在该行所在的列判断是否为最小值
      {
        flag=1;
        break;
      }
    }
    if(flag==0)
    {
        printf("%d %d\n",i,temp);
        count++;
    }
  }
    if(count==0)
        printf("NONE");
}

改后数组

#include<stdio.h>
int main()
{
  int i,j,k,temp,flag;
  int count=0;
  int n;
  scanf("%d",&n);
  int a[n][n];
  for(i=0;i<n;i++)
  {
    for(j=0;j<n;j++)
    {
      scanf("%d",&a[i][j]);
    }
  }
  for(i=0;i<n;i++)
  {
    for(j=0;j<n;j++)
    {
      flag=0;
      temp=0;
      for(k=0;k<n;k++)
      {
        if(a[i][j]<a[i][k])
          flag=1;                   //不是行中最大的,令flag=1
      }
      for(k=0;k<n;k++)
      {
        if(a[i][j]>a[k][j])
          temp=1;                 //不是列中最大的,令temp=1
      }
      if(flag==0&&temp==0)
      {
        count++;
        printf("%d %d",i,j);
      }
    }
  }
  if(count==0)
        printf("NONE");
    return 0;
}

3.2.3 PTA提交列表及说明

Q1:一开始的作法,是想先找出该行上最大的值,而后在判断所在的列中它是否是最小的,可是有个测试点过不了,就是有两个同样的极值的时候,它会两个都输出
A1:后来换了个想法,判断该行中,是否有比它更大的,若是有令flag=1,再判断该列中是否有比它更小的,有的话令temp=1,当flag和temp都为0时就存在鞍点了
A2:虽然仍是存在两个同样极值时,它都输出了,但是整个都过了,这有bug啊!

3.3 PTA题目3

查验身份证
一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。
按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理,只检查前17位是否全为数字且最后1位校验码计算准确。若是全部号码都正常,则输出All passed。
校验码的计算规则以下:
首先对前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,i,j,k,count,count1,整型数组ch,整型数组sum
定义字符型数组num,字符型数组M,字符型数组Z 
输入N 
for i=0 to N do
    初始化count=0,sum[i]=0
    输入字符串
    for j=0 to 17 do
        if num[i]大于0而且小于9               
            次数count加1
            sum[i]+=((num[j]-'0')*(ch[j]))     //根据题目要求计算和 
        end if
    end for
    if 知足是数字的次数不足17次
        输出num数组
    else
        for k=0 to 11 do
            if  sum[i]%11==Z[k]                  //将它获得的模和Z数组比较,找出对应M数组中的位置 K 
                if (num[17]-'0')!=M[k]       //将身份证最后一位和M数组中的第k位比较 
                    输出num数组
                else
                    身份证合法的个数加1
            end if
        end for
    if 两个条件都知足便是合法身份证的个数和输入查验的个数同样
        输出All passed
    end if
end for

3.3.2 代码

#include<stdio.h>
int main()
{
  int N;
  scanf("%d",&N);
  getchar();
  int sum[N];
  char num[19],X;
  char M[11]={1,0,'X'-'0',9,8,7,6,5,4,3,2};//题目中的 Z值 
  char Z[11]={0,1,2,3,4,5,6,7,8,9,10};//题目中的校验码M 
  int ch[19]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//题目中权重分配 
  int i,j,k;
  int count,count1=0;
  for(i=0;i<N;i++)
  {
    count=0;
    sum[i]=0;
    gets(num);
    for(j=0;j<17;j++)
    {
        if(num[j]<='9'&&num[j]>='0')
        {
            count++;
            sum[i]+=((num[j]-'0')*(ch[j]));
        }
    }
    if(count!=17)                                               //判断前十七个数是否为数字 
    {
        puts(num);
    }
    else
    {
        for(k=0;k<11;k++)
        {
            if(sum[i]%11==Z[k])                      //将它获得的模和Z数组比较,找出对应M数组中的位置 K 
            {
                if((num[17]-'0')!=M[k])          //将身份证最后一位和M数组中的第k位比较 
                {
                    puts(num);
                }
                else 
                {
                    count1++;                    //号码正确的个数 
                }
            }
        }
    }if(count1==N)
    printf("All passed");
  }
}

3.3.3 PTA提交列表及说明

Q1:又是提交了好屡次,测试点一两个过不了,还越改越不对,绝望.jpg
A1:慢慢调试,发现了好多问题,像第二次进去时,count,sum之类的没有初始化,还有字符数组时忘记减去‘0’,致使值算出来是错的,看来以前的测试点也是混过去的了。
Q2:改得差很少了,觉得此次应该对了,但是还有个最大n的测试点不对,请教了一下大佬,而后发现是X的问题,在我把它们都转成数字的同时,没有考虑到X对应的那个值也被转化了
A2:原本还想着分类讨论一下,而后大佬告诉我直接在M数组改一下就行了,emmm,有道理,以为本身智商堪忧了,后来终于过了,感动.jpg

4. 代码互评

4.1 代码截图

同窗代码函数

个人代码学习

4.2 二者的不一样

1.总体思路不一样:同窗的思路是用hash数组来找相同的数字,而个人思路是遍历两个数组直接进行比较
2.对方优势:代码更加灵活,可扩展性也比较好
3.个人优势:思路比较直接,易懂
相关文章
相关标签/搜索