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.個人優勢:思路比較直接,易懂
相關文章
相關標籤/搜索