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

无人久伴 提交于 2019-12-04 18:50:25

0.展示PTA总分

1.本章学习总结

1.1 学习内容总结

1.1.1一维数组

  • ①一维数组的定义格式:类型名 数组名 [数组长度];

  • ②一维数组的引用形式:数组名 [下标]

  • ③下标的取值范围:[0,数组长度-1]

  • ④只能引用单个的数组元素,不能一次引用整个数组

  • ⑤引用数组元素时,方括号内是表达式,代表下标,也可以是变量,而定义数组时方括号内是常量表达式,可以包括常量和符号常量,但不能包含变量

  • ⑥对数组元素赋初值格式:类型名 数组名 [数组长度] = {初值表};

    可对全部元素赋值,如 int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

    也可对部分元素赋值,如 int b[20] = {0,1};//表示对b数组的前两个元素赋初值

  • ⑦静态储存的数组如果没有初始化,系统将自动给所有元素赋0

1.1.2二维数组

  • ①数组的定义格式:类型名 数组名 [行长度][列长度];

  • ②二维数组的引用形式:数组名 [行长度][列长度]

  • ③二维数组先存放第0行的元素,再存放第1行的元素...每一行元素再按照列的顺序的存放

  • ③二维数组的分行式赋初值格式:类型名 数组名 [行长度] [列长度] = {{初值表0},...,{初值表k},...};

    可对全部元素赋值,如 int a[2][3] = { {1,2,3},{4,5,6},{7,8,9} };

    也可对部分元素赋值,如 int b[4][3] = {{1,2,3},{},{4,5} };//表示对b数组的第0行和第2行的前两个元素赋初值

1.1.3一维字符数组

  • 一维字符数组的定义、初始化和引用与其他类型的一维数组一样

1.1.4字符串

  • ①字符串常量就是用一对双引号括起来的字符序列,即一串字符,如“happy”

  • ②字符串有一个结束标志'\0',如“happy”由六个字符组成即'h','a','p','p','y','\0',前五个是字符串的有效字符,'\0'是字符串结束符

  • ③将字符串存入字符数组时,由于'\0'的存在,数组的长度至少是字符串的有效长度+1

  • ④字符串的存储——数组初始化

    字符数组的初始化还可用字符串常量,如 static char s [6] = {"happy"};或 static char s [6] = "happy";

    还可以采用赋值和输入的方法,如 static char s [6]; s[0] = 'a'; s[1] = '\0';

  • 区分"a"和'a',"a"是字符串常量,包括'a'和'\0'两个字符,而'a'是字符常量,只有一个字符,可以赋给字符变量

    所以 static char s [6]; s[0] = 'a'; s[1] = '\0';等价于 static char s [6] = “a”;

  • 在程序中要将结束符'\0'存入字符数组,否则字符串就不能正常结束,影响后面操作

1.1.5在数组中查找数据

①遍历法,即挨个找,找到就输出该数在数组中的下标

void arrayFind(int a[MAX], int n, int number)    //传入数组、数组长度和要找的数
    {
    int i;

    for (i = 0; i < n; i++)
        {
        if (a[i] == number)
            {
        printf("%d\n", i);    //找到元素,打印下标
            }
        }

    return 0;
     }

②二分法,即将要找的数与数组的中间数比较,如果相同就输出中间数的下标,否则将要找的区间压缩

void arrayFind(int a[MAX], int n, int number)    //传入数组、数组长度和要找的数
{
int left = 0;
int right = a[n];
int mid;

while (left <= right)
{
    mid = (left + right) / 2;
    {
        if (number == a[mid])
        {
            printf("%d", mid);  //找到元素,打印下标
            return 0;
        }
        else if (number < a[mid])
        {
            right = mid - 1;
        }
        else if (number > a[mid])
        {
            left = mid + 1;
        }
    }
}

return 0;
 }

1.1.6在数组中插入数据

int main()
{
    int i;
    int j;
    int a[MAX+1];    //先假定该数组已按从小到大排列,且该数组长度为插入后的长度
    int number;

    用循环给数组赋值
    输入要插入的数

    for(i=0;i<MAX;i++)
        {
            找到比该数大的数组元素的下标
            break;
        }
    for(j=MAX-1; j>=i; j--)
        {
            将该下标(包括其本身)后面的元素下标加一
            将该数插入该下标所在位置
        }
    输出插入后的数组
    return 0;
}

1.1.7删除数组中的数据

①一般法

int main()
{
    int i;
    int j;
    int a[MAX];
    int number;

    用循环给数组赋值
    输入要删除的数

    for (i = 0; i <= MAX - 1; i++)
        {
        找到要删除的数,记录下标
            {
            for (j = i; j <= MAX - 2; j++)
                    {
                将该下标后面的元素向前移一位,实现覆盖 
                }
            }
            跳出循环
         }

    输出删除后的数组

    return 0;
}

②记录下标法

int main()
{
    int a[MAX];
    int number;
    int delectIndex;

    用循环给数组赋值
    输入要删除的数

    for (i = 0; i <= MAX - 1; i++)
        {
        找到要删除的数的下标
            {
                    delectIndex=i;
            }
         }

    for(i=delectIndex;i<=MAX-2;i++)
          {
             将该下标后面的元素向前移一位,实现覆盖 
          }

    输出删除后的数组

    return 0;
}

1.1.8数组排序

①冒泡法

相邻元素两两比较,每趟将最值沉底即可确定一个数在结果的位置,确定元素位置的顺序是从后往前,其余元素可能作相对位置的调整。可以进行升序或降序排序。

int main()
{
    int a[10];
    int i;
    int j;
    int temp;

    for (i = 0; i < 10; i++)
        {
        scanf("%d", &a[i]);
        }

    for (j = 0; j < 9; j++)    /*外循环控制排序趟数,n个数排n-1趟*/
        {
        for (i = 0; i < 9 - j; i++)   /*内循环每趟比较的次数,第j趟比较n-j次*/
            {
            if (a[i] > a[i + 1])    /*相邻元素比较,逆序则交换*/
                {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
                }
            }
         }

      for (i = 0; i < 10; i++)
            {
            printf("%d", a[i]);
            }

    return 0;
}

②选择法

每趟选出一个最值和无序序列的第一个数交换,n个数共选n-1趟。第i趟假设i为最值下标,然后将最值和i+1至最后一个数比较,找出最值的下标,若最值下标不为初设值,则将最值元素和下标为i的元素交

换。

int main()
{
int a[10];
int i;
int j;
int k;
int temp;
int n = 10;

for (i = 0; i < 10; i++)
    {
    scanf("%d", &a[i]);
    }

for (i = 0; i < n - 1; i++)   /*外循环控制趟数,n个数选n-1趟*/
    {
    k = i;             /*假设当前趟的第一个数为最值,记在k中 */
    for (j = i + 1; j < n; j++)  /*从下一个数到最后一个数之间找最值*/
        {
        if (a[k] < a[j])     /*若其后有比最值更大的*/
            {
            k = j;           /*则将其下标记在k中*/
            }
        }
        if (k != i)        /*若k不为最初的i值,说明在其后找到比其更大的数*/
            {
            temp = a[k]; 
            a[k] = a[i]; 
            a[i] = temp; 
            } /*则交换最值和当前序列的第一个数*/
      }

for (i = 0; i < 10; i++)
    {
    printf("%d", a[i]);
    }

return 0;
}

③插入法

将序列分为有序序列和无序列,依次从无序序列中取出元素值插入到有序序列的合适位置。初始是有序序列中只有第一个数,其余n-1个数组成无序序列,则n个数需进n-1次插入。寻找在有序序列中插入位置

可以从有序序列的最后一个数往前找,在未找到插入点之前可以同时向后移动元素,为插入元素准备空间

int main()
{
int a[10];
int i;
int j;
int temp;

for (i = 0; i < 10; i++)
{
    scanf("%d", &a[i]);
}

for (i = 1; i < 10; i++)     /*外循环控制趟数,n个数从第2个数开始到最后共进行n-1次插入*/
    {
        temp = a[i];     /*将待插入数暂存于变量t中*/
        for (j = i - 1; j >= 0 && temp > a[j]; j--)      /*在有序序列(下标0 ~ i-1)中寻找插入位置*/
            {
            a[j + 1] = a[j];     /*若未找到插入位置,则当前元素后移一个位置*/
        }
        a[j + 1] = temp;        /*找到插入位置,完成插入*/
    }

for (i = 0; i < 10; i++)
    {
    printf("%d ", a[i]);
    }

return 0;
}

1.1.9数组做枚举用法的案例

  • ①在课本例题“调查电视节目收欢迎程度”中,将节目编号1~8作为数组下标进行计数操作

  • ②在PTA“找重复数据I”一题中,用hush数组的下标对应每个数据,最后对hush数组进行遍历查重

  • ③在PTA“阅览室”一题中,用数组下标存放书号

1.1.10哈希数组用法案例

  • ①在PTA“找重复数据I”一题中,先定义一个静态储存的数组hush,然后遍历原数组,当原数组中的元素与hush数组的下标相等时,hush数组该下标所对应的值变为1,之后若再遇到hush的值为1的,即表示

有重复数据

1.2 本章学习体会

1.2.1学习感受

做数组PTA时,一维数组倒是还好,二维数组我感觉比较棘手的是内外两层循环与行列的结合运用,而字符数组就有点难办了,对字符数组的赋值跟输出的认识还是有点模糊。还有就是感觉我的代码的行数常常

比他人要多一些。

1.2.2代码量

两周代码量大约1016行

2.PTA实验作业

2.1出生年

2.1.1伪代码

int main()
 {
    int n;      //目标年份中不同数字的个数
    int i;      //循环用的
    int j;      //循环用的
    int year;       //出生年份
    int flag = 0;       //记录有几个不同数
    int count = 0;      //年纪
    static int b[10];       //将年份分拆成4个后,存入该数组

    输入出生年份和目标年份中不同数字的个数

    while (1)


    将年份拆分成4个后,按下标存入b数组

        for (i = 0; i < 10; i++)
        {
         遍历b数组,有元素不为0的,flag加一
        }

        当flag达到n时,输出结果,并结束程序

        若flag没达到要求,将flag和b数组清零

        count++;
        year++;         //年份与年纪都加一

    end while

    return 0;
}

2.1.2代码截图

2.1.3造测试数据

输入数据 输出数据 说明
2000 4 13 2013 正常数据
6666 4 35 6701 正常数据
11111 3 9 11120 正常数据
9999 3 13 10012 正常数据
9999 4 程序炸了
666 5 程序炸了

2.1.4PTA提交列表及说明

  • 选这题是因为我觉得这题挺好玩的,做的过程中也换了不少思路,虽然现在看当时的想法很笨(可能现在也是,哈哈哈),但终归是有了一些收获的。

  • 另外我有个小毛病,我无论有没有修改后都会习惯地就点PTA的提交来看各个测试的情况,所以有些错误其实是重复的,因此我会适当跳过一些。

  • Q1:编译错误

  • A1:单纯的语法错误。

  • Q2:部分正确

  • A2:同时出现了运行超时、段错误,经分析,是发生了数组越位,导致循环不能正常退出,我于是选择用下标的方法处理拆分后的年份数据。

  • Q3:多种错误

  • A3:有点尴尬,换了一套算法后就全错了(哈哈哈),经分析,是在flag没达到要求时没有将flag和b数组清零,导致运行结果出错,在多了清零语句后,就通过所有测试点了。

2.1找鞍点

2.1.1伪代码

int main()
{
    int n;      //表示几阶的数组
    int i;      //循环用的
    int j;      //循环用的
    int m;      //循环用的
    int lineMax;    //行最大的数
    int rowMin;     //列最小的数
    int lineDate;   //行最大的数的下标
    int rowDate;    //列最小的数的下标
    int a[N][M];    //数组

    输入阶数

    当阶数为1时,直接输出0 0

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
            给数组赋值
    }

    for (i = 0; i < n; i++)
    {
        rowDate = 0;
        for (j = 0; j < n; j++)
        {
            每行找出列最小的数,记录其数值跟下标
        }
        for (m = 0; m < n - 1; m++)
        {
            找该列行最大的数,记录其数值跟下标
        }

        若两次查找出的数相同,表示该数符合条件,输出其行列下标,结束程序

    }

    printf("NONE");     //找不到输出NONE

    return 0;    
}

2.1.2代码截图

2.1.3造测试数据

输入数据 输出数据 说明
4 1 7 4 1 4 8 3 6 1 6 1 2 0 7 8 9 2 1 正常数据
3 2 5 6 A 4 1 0 8 5 6 1 2 有非数字
3 -1 -5 -6 -2 -5 -1 -3 -6 -10 2 0 全负数

2.1.4PTA提交列表及说明

  • 我无论有没有修改后都会习惯地就点PTA的提交来看各个测试的情况,所以有些错误其实是重复的,因此我会适当跳过一些。

  • Q1:部分正确

  • A1:经分析,没有考虑n=1的情况,补充了几条语句后就通过了“n最小”的测试点。

  • Q2:部分正确

  • A2:经过几次调试都没过“最大规模,有并列极值元素,最后一个是鞍点”这一测试点,看了超新星平台后,就全过了。

2.1出生年

2.1.1伪代码

2.1.2代码截图

2.1.3造测试数据

输入数据 输出数据 说明
0 1.0000 题目极限数据
5 148.4132 题目极限数据
-5 0.0067 负数

2.1.4PTA提交列表及说明

  • 我无论有没有修改后都会习惯地就点PTA的提交来看各个测试的情况,所以有些错误其实是重复的,因此我会适当跳过一些。

3.阅读代码

  • 代码功能:将输入的一段文字沿着矩阵以螺旋模式进行编码
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!