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

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

    展示3张关于“数组题目集”分数截图。


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

    1.1 学习内容总结

    整理数组这章学习主要知识点,必须包含内容有:
    (1)数组查找数据

    • 顺序查找法
      顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。该查找法思路较为简单,容易上手。
    /*    举一个例子   */
    /*在给定的一组数中查找是否有数字 2*/
    #include<stdio.h>
    int main()
    {
    	int i;
    	int a[5] = { 1, 2,3,4,5 };
    	int loc;//记录位置;
    	int flag = 0;
    	for (i = 0; i < 5; i++)
    	{                                                        //遍历数组,寻找2;
    		if (a[i] == 2)
    		{
    			loc = i;
    			printf("2在这个数组的第%d项",loc);
    			flag = 1;
    		}
    	}                                                        //判断是否发现了数2;
    	if(flag==0)
    	printf("2不在这个数组中。");
    	
    }
    
    • 二分查找法
      基本思想:也称为是折半查找,属于有序查找算法。确定上界下界(left,right),用给定值k先与中间结点(mid=(left+right)/2)的关键字比较,中间结点把线性数组分成两部分,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪一部分,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
    /*同样举一个例子*/
    /*用二分法在一个有序数列{1,2,3,4,5,6,7,8,9,10}中查找key值,若找到key则输出其在数组中对应的下标,否则输出not found。*/
    #include <stdio.h>
    int binarySearch(int a[], int key)
    {
    	int low = 0;                               //定义上界下界,他的中间值mid;
    	int high = 9;
    	int mid;
    	int loc;
    
    	while (low <= high)                        //循环控制条件,如果下界大于上界则表示可以结束循环;
    	{
    		mid = (low + high) / 2;
    		if (a[mid] < key)
    			low = mid + 1;
    		else if (a[mid] > key)
    			high = mid - 1;            //判断在线性数组的哪一部分,然后进行再赋值计算;
    		else
    		{
    			loc = mid ;
    			return loc;
    		}
    	}
    	return 0;
    }
    int main() 
    {
    	int i;
    	int key;
    	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
    
    	scanf("%d", &key);
    	
    
    	if (binarySearch(a, key))
    	{
    		printf("weizhi:%d", binarySearch(a, key));
    	}
    	else
    	{
    		printf("not found");
    	}
    	return 0;
    }
    

    需要说明的是:使用二分查找法元素必须是有序的,如果是无序的则要先进行排序操作。二分法查找大大减少了用时,是一种高效的查找方法;


    (2)数组中如何插入数据

    #include<stdio.h>
    #define N 10
    void InputArrery(int a[], int n, int date);
    int main()
    {
    	输入数的个数;
    	for i=0 to i<n;
    	输入要插入的数date;
    	调用函数插入InputArrery(a, n, date);
    
    	输出数组;//注意插入数之后,项数的改变;
    }
    
    void InputArrery(int a[], int n, int date)
    {
         for i=0 to i<n
         寻找第一个大于date的数;
         记录位置loc=i;
         end for;
    	
         临时变量temp存储date;
         a[n]=date;
         for i=n-1 to t>=loc           //将每一项的值赋给后面一项,达到插入的目的;
         a[i + 1] = a[i];
         a[i] = temp;
    }
    

    (3)数组中如何删除数据

    • 方法一:移位删除法
      思路:有n项的数组将要删除的i项放在数组的最后面,输出的时候只输出n-i项即进行了删除;
    int date;//被寻找的数据;
    int temp;
    for i=0 to i<n
    输入n项数
    for i=0 to i<n
    遍历数组,寻找值进行交换;
    if(a[i]==date) temp=a[n-1]; a[n-1]=a[i]; a[i]=temp;//交换数组;
    for i=0 to i<n-1
    输出n-1项数
    
    • 方法二:覆盖法;
    int length;//计算数组长度;
    for int i=0 to i<length-1
    for int j=i+1 to j<length  //注意:此时第三个表达式空出,因为当找到重复的数据,后面的数往前覆盖之后,应该再进行一次对比
    if (a[i] == a[j])//判断如果出现相同数据,则将后面的数据往前移一位
    {
    for int k=j to k<length-1
    {
     a[k]=a[k+1];
    }
    length--;//记录数组长度的变量相应减1 
    }
    else j++;//没有的时候才j++;
    
    for i = 0 to i<length
    输出数组;
    

    (4)数组中排序方法。

    • 冒泡法
      其原理为从a[0]开始,依次将其和后面的元素比较, 若a[0] > a[i],则交换它们,一直比较到a[n]。同理对a[1], a[2], ...a[n - 1]处理,即完成排序。下面列出其代码:
    void bubble(int* a, int n) /*定义两个参数:数组首地址与数组大小*/
    {
    	int i, j, temp;
    	for (i = 0; i < n - 1; i++)
    		for (j = i + 1; j < n; j++) /*注意循环的上下限*/
    			if (a[i] > a[j]) 
                            { 
    				temp = a[i];
    				a[i] = a[j];
    				a[j] = temp;
    			}
    }
    

    冒泡法原理简单,但其缺点是交换次数多,效率低。
    下面介绍一种源自冒泡法但更有效率的方法“选择法”。

    • 选择法
      选择法循环过程与冒泡法一致,它还定义了记号k = i, 然后依次把a[k]同后面元素比较,若a[k] > a[j], 则使k = j.最后看看k = i是否还成立,不成立则交换a[k], a[i], 这样就比冒泡法省下许多无用的交换,提高了效率。
    void choise(int* a, int n)
    {
    	int i, j, k, temp;
    	for (i = 0; i < n - 1; i++) {
    		k = i; /*给记号赋值*/
    		for (j = i + 1; j < n; j++)
    			if (a[k] > a[j]) k = j; /*是k总是指向最小元素*/
    		if (i != k)
    		{ /*当k!=i是才交换,否则a[i ] 即为最小*/
    			temp = a[i];
    			a[i] = a[k];
    			a[k] = temp;
    		}
    	}
    }
    

    (5)数组做枚举用法,有哪些案例?
    枚举法:【https://blog.csdn.net/wq3028/article/details/76204690】
    程序设计中,存在着一种“数据集”,他的数值在程序中是稳定的,而且元素的个数是有限的,通常可以使用一个数组元素代替一种状态。

    (6)哈希数组用法
    哈希算法:【https://blog.csdn.net/u014209205/article/details/80820263】
    应用:hash被用在加密等场合,但在一般的应用程序代码中,也可以用它来存贮简单的数据,这样代码的效率会高很多。


    1.2 本章学习体会

    • 数组是一种应用性很强的工具。通过对本章内容的学习,可以利用数组解决很多问题。数组就是一种对数据暂时存储的容器,运用它可以同一时间存储多个数据,并且根据要求对所给出的数据进行处理。利用正确的方法可以实现问题快速高效地解决,比如说查找指定数据,可以遍历数组查找,也可以用二分法查找。将数据排序,再也不用设abcd···等多个变量,节约了代码量。并且还可以利用这部分地知识解决实际生活中的问题,比如设计一个最受欢迎节目统计器,寻找多次出现的数据,各种进制之间的相互转换等。最重要的是,利用它可以解决许多线性代数问题(因为它经常研究矩阵)。认真学好这部分的知识对后面指针的学习也有很大帮助。
    • 计算这两周代码量
    时间 代码量
    十一周 1203
    十二周 1502

    2.PTA实验作业(7分)

    2.1 题目名1 数组元素的删除

    2.1.1 伪代码

    int num;//被删除的数据;
    int temp;//暂时变量,用于交换;
    
    for i=0 to i<n
    输入n项数
    end for
    
    输入要删除的数据;(假设删除i项)
    for i=0 to i<n
    遍历数组,寻找值进行交换;
    if(a[i]==num) temp=a[n-1]; a[n-1]=a[i]; a[i]=temp;//交换数组;将要删除的数据放在整个数组的后头;
    end for
    
    for i=0 to i<n-i
    输出n-i项数
    

    2.1.2 代码截图

    2.1.3 造测试数据

    测试数据 运行结果 结果
    数的量:10 每个数:1 2 3 4 5 6 7 8 9 10 删除的项:4 3 2 4 6 1 4 5 7 8 10 正确
    数的量:2 每个数:1 2 删除的项:1 2 正确
    数的量:0 每个数:1 2 删除的项:1 乱码

    2.1.4 PTA提交列表及说明

    截图PTA提交列表,介绍碰到问题及解决办法。如:

    提交列表说明:

    • 1.格式错误:关于结尾有空格的问题,可以让a[0]单独输出;
    • 2.答案错误:主要是越界的问题。控制输出的个数;

    2.2 题目名2 数组循环左移

    2.2.1 数据处理

            int n, m;//移动次数;
    	int a[N];
    	int temp;
    
    	scanf("%d %d", &n, &m);
    	for i = 0 to  i < n
    	{
    		输入数据;
    	}
    	end for
    
    	for i = 1 to  i<= m
    	{
    		temp = a[0];//储存头号数据;
    		for k = 0 to k < n		
    		进行后一项与前一项的交换;
    	}
    	end for
    
    	for i = 0 to i < n - 1
    	{
    	输出结果;
    	}
    	end for;
    

    2.2.2 代码截图

    2.2.3 造测试数据

    测试数据 运行结果 结果
    输入几个数:8 移动几次:3 数:1 2 3 4 5 6 7 8 4 5 6 7 8 1 2 3 正确
    输入几个数:2 移动几次:3 数: 5 6 6 5 正确

    2.2.4 PTA提交列表及说明

    • 1.多种错误:刚开始的时候没有思路,一直想把前面几项当成一个整体进行移动,但是多种错误;
    • 2.答案正确:后来在网上搜到了整体移动的方法;
    • 3.答案正确:看了超星平台的视频之后,感觉每次只移动一个数字,多次进行移动的效率高,且容易理解;

    2.3 题目名3 阅览室

    2.3.1 数据处理

    int main()
    {
    	scanf("%d", &n);//输入要查找N天的纪录;
    
    	for i = 1 to i <= n
    	{
    		k = 0;
    		while (1)
    		{
    			scanf("%d %c %d:%d", &number, &op, &hour, &minute);
    			if (number == 0)     break;                 //输入0则表示退出;
    			record[k][0] = number;
    			record[k][1] = op;                   //利用二维数组进行数据的存储;
    			record[k][2] = hour * 60 + minute;
    			k++;
    		}
    		AverageTime(record, k);
    	}
    	return 0;
    }
    
    void AverageTime(int record[][3], int k)//向下查找并且进行计算;
    {
    	for i = 0 to i < k
    	{
    		if (record[i][1] == 'S')//以S为开始;
    		{
    			for j = i + 1 to j < k
    			{
    				if (record[j][0] == record[i][0] && record[j][1] == 'S') break;
    				if (record[j][0] == record[i][0] && record[j][1] == 'E')//以E 为结束;
    				{
    					count++;
    					avg = avg + record[j][2] - record[i][2];
    					break;
    				}
    			}
    			end for
    		}
    	}
    	end for
    	
    }
    

    2.3.2 代码截图


    2.3.3 造测试数据

    /*1 S 08:10      //测试数据(1)               
    2 S 08:35                                     
    1 E 10:00                                    
    2 E 13:16                                    
    0 S 17:00                                    
    0 S 17:00
    3 E 08:10
    1 S 08:20
    2 S 09:00
    1 E 09:20              
    0 E 17:00*/
    
    测试数据 运行结果 结果
    测试数据(1) 2 196 0 0 1 60 正确
    0(表明没有查询) 正确

    2.3.4 PTA提交列表及说明

    • 1.多种错误:刚开始的时候没有思路;
    • 2.编译错误:ctrl+v时候发生了错误;
    • 3.答案正确:看了超星平台的视频之后,按照老师给的思路进行了编译,最后成功完成了代码;

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

    打印螺旋方阵———洋葱遍历法;

    题目描述:

    遍历方式:

    优点:

    • 该代码运用了很详细的注释,比较直观的描述了数组打印的过程;
    • 总体思路上来讲,将数组从外层到内层不断地存放,打印出一个矩形(n为其边长),外面有一个大的for循环,判断循环结束的条件是是s>e;解决了我pta上没有解决的内容。
      我的代码:

      更加优雅的解题方法:

      核心思路:
      当我们遍历每一行、每一列时,都把最后一个元素留着,等到下一步再遍历。这样的话,我们每次把矩阵剥离一圈,都对应 4 个非常规整的循环,边界条件清晰不易出错。
  • 相关阅读:
    【BZOJ1014】【JSOI2008】火星人prefix
    [agc011e]increasing numbers
    NOIp2018模拟赛四十一
    拉格朗日插值&&快速插值
    NOIp2018模拟赛四十
    (2016北京集训十四)【xsy1557】task
    (2016北京集训十四)【xsy1556】股神小D
    数据泵导入ORA-39082报错解决
    OracleDBA职责—备份与恢复技术—概念
    OracleDBA职责—备份与恢复技术—RMAN3
  • 原文地址:https://www.cnblogs.com/shenchao123/p/11872925.html
Copyright © 2011-2022 走看看