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 个非常规整的循环,边界条件清晰不易出错。
posted @ 2019-11-17 21:08  不会soma  阅读(366)  评论(0编辑  收藏  举报