zoukankan      html  css  js  c++  java
  • C语言博客作业04--数组

    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”

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

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

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

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

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

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

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

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

    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
    ", 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.3IP地址转换

    2.1.1伪代码

    #include <stdio.h>
    int main()
    {
        int i;				//循环用的
        char a[35];			//存放字符
        int number1 = 0;	//地址数1
        int number2 = 0;	//地址数2
        int number3 = 0;	//地址数3
        int number4 = 0;	//地址数4
    
        输入字符
    
        for (i = 0; i < 8; i++)
        {
    	    将前八个数值转换成十进制
        }
        for (i = 8; i < 16; i++)
        {
    	    将第二个的八个数值转换成十进制
        }
        for (i = 16; i < 24; i++)
        {
    	    将第三个的八个数值转换成十进制
        }
        for (i = 24; i < 32; i++)
        {
    	    将后八个数值转换成十进制
        }
    
        输出结果
    
        return 0;
    }
    

    2.1.2代码截图

    2.1.3造测试数据

    输入数据 输出数据 说明
    11001100100101000001010101110010 204.148.21.114 正常数据
    110011001001010000010101011100101 204.148.21.114 超出32位的数据
    1100110010010100000101010111001 204.148.21.76 小于32位的数据
    11001100100101000001010101110018 204.148.21.122 有非二进制的数据
    1100110010010100000101010111001A 204.148.21.131 有非数字的数据

    2.1.4PTA提交列表及说明

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

    • Q1:答案错误

    • A1:在设置了多个printf语句后,发现最后一个字符并没有进入程序,经排查,最终发现是在定义数组长度时只设置了32个,无法达到题目要求,在扩大数组长度后,就全过了。

    3.阅读代码

    • 代码功能:将输入的一段文字沿着矩阵按一定的规则进行编码加密

    • 优点一:用getchar();语句吸收换行符

    • 优点二:用isRow = !isRow;使程序能进入if语句跟下面的else语句

    • 优点三:通过记录下标达到对每一行或每一列的数据处理,并且通过多个if else语句实现了螺旋编码

  • 相关阅读:
    .net中对象序列化技术
    new、virtual、override
    如何检测指定的Windows服务是否启动
    c#中的GetUpperBound,GetLowerBound方法
    C#.net中的rank方法
    实现MD5算法
    用C#实现DES加密解密封装
    [转]JSP或servlet中(以及上传下载文件)中文乱码或不显示的解决方案
    [转]runOnUiThread 、 Handler 对比(一)
    [转]使用popBackStack()清除Fragment
  • 原文地址:https://www.cnblogs.com/g1215161797/p/11875392.html
Copyright © 2011-2022 走看看