一、数组知识点
1、数组定义:数组是一组具有相同类型的变量集合。其中每一个元素称为数组元素(或下标变量);用来标识一组相同类型的数据的统一名字称为数组名;C程序通过数组的下标实现对数据元素的访问。
2、数组格式:例如int score[5]的形式,int代表该数组的基类型,即数组中元素的类型。下标的个数表明数组的维数。
3、二维数组的定义:二维数组用两个下标确定各元素在数组中的顺序,可用排列成i行j列的元素表示。第一维的长度代表数组每一列的元素个数,第二维的长度代表数组每一行的元素个数;二维数组是一维数组的推广。
4、内存占用:一维数组在内存占用的字节数为:数组长度基本型,二维数组占用字节数为:第一维长度第二维变长度*基本型。
5、数组的初始化,主要有三种:
(1)声明时,使用 {0} 初始化;
(2)使用memset;
(3)用for循环赋值。
对三种方法的选取:
1)for 最浪费时间,不建议(其实memset内部也是用循环实现的,只不过memset经过了严格优化,所以性能更高);
2){0} 可能有移植性问题,虽然绝大多数编译器看到{0} 都是将数组全部初始化为0, 但是不保证所有编译器都是这样实现的;
3)综合1)、2), 推荐使用memset方法。
6、向函数传递数组:若要把一个数组传递给一个函数,那么只要使用不带方括号的数组名作为函数实参调用函数即可。传递时仅仅是数组名,不带方括号和下标。
数组名代表数组第一个元素的地址,用数组名作函数实参实际上是将数组的首地址传给被调函数。
7排序和查找:
(1)排序是把一系列无序的数据按照特定的顺序重新排列为有序序列的过程。
主要有交换排序,冒泡排位和选择排序。
(i)交换排序:借鉴了求最大值,最小值的思想,按升序排列的基本过程为:先将第一个数分别与后面的数进行比较,若后面是的数小,则交换和第一个数的位置,否则不交换:这一轮结束之后,则求除了一个最小的放在第一个位置,然后进行第二轮比较,但这种交换效率低。
(ii)冒泡排序:将相邻两个数进行交换,重复的过程,一般,如果有N个数进行排序,则需进行N-1起泡。
(iii)选择排序:在交换排序的基础上,找出余下的数中的最大值再与地I+1个数进行交换,这样每一轮比较中最多只有一次交换操作,这个算法最多只有N—1次交换操作。
但实际中用到排序常用sort函数(默认升序),头文件为algorithm。
(2)查找:在数组中搜索一个特定元素的处理过程称为查找。主要有线性查找(也称顺序查找)和折半查找。
(i)线性查找:条件:不要求数据表已经排好序。工作原理: 从线性数据表中的第一个(或最后一个)记录开始查找;依次将记录的关键字与查找关键字进行比较 ;
(当某个记录的关键字与查找关键字相等时,即查找成功 )
(反之,查完全部记录都没有与之相等的关键字,则查找失败 )
折半查找:要求所要査找的数据必须是有序序列。该算法的基本思想是将所要査找的序列的中间位置的数据与所要査找的元素进行比较,如果相等,则表示査找成功,否则将以该位置为基准将所要査找的序列分为左右两部分。接下来根据所要査找序列的升降序规律及中间元素与所查找元素的大小关系,来选择所要査找元素可能存在的那部分序列,对其采用同样的方法进行査找,直至能够确定所要查找的元素是否存在。
8、运用数组注意事项:
(1)C语言中的数组的下标都是从0开始的。
(2)scanf(" %s",字符数组名)只能输出一个单词,遇空格即停止;gets能输入一个字符串,包括空格。
(3)在定义数组时不能使用变量定义数组的大小。
(4)数组要定义成全局数组,尽量不要在函数内定义。
(5)数组的二维的长度永远都不能省略。而当形参被声明为二维数组时,可以省略数组第一维的长度声明。
二、可以解决的问题
1、计算鞍点,模拟简单游戏,如扫雷
2、用于矩阵的变换,如换行换列,矩阵的转置,为解决高次线性方程组提供基础
3、用于数据的处理,如升降序排列,逆序重放,倒置排序
4、计算向量的线性运算,如向量点积运算
5、用于模拟一些生物规律,如细菌的繁殖与扩散
6、用于解决实际生活问题,如年龄与疾病,校门外的树。
7、模拟游戏规律,如石头剪刀布,做游戏
下面以校门外的树为例,说明数组的功能;
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入 第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。
对于20%的数据,区域之间没有重合的部分;
对于其它的数据,区域之间有重合的情况。
输出 包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。
代码如下:
#include
using namespace std;
int main()
{
bool a[10010];
int L,M,i,j,p,q,k,s;
cin>>L>>M;
for(i=0;i<10000;i++)
{
a[i]=true;
}
for(j=0;j<M;j++)
{
cin>>p>>q;
for(k=p;k<=q;k++)
{
a[k]=false;
}
}
s=0;
for(i=0;i<=L;i++)
{
if(a[i]==true)
s++;
}
cout<<s<<endl;
return 0;
}
三、总结与感悟
通过学习数组,自己对C语言的了解也进一步加深,自己能解决的问题也是有了量的提升,数组作为一种工具,确定帮助我们解决很多的问题,自己也慢慢熟悉了它的一些语言习惯,
通过做openjudge上的习题,发现二维数组与矩阵有着密切的联系,因为我是数学专业的学生,所以学好数学,解决高阶矩阵的问题便离不开数组,这让我发现了C语言的重要作用,以前总是感觉他仅仅是一门编程语言,没想过它和数学的联系如此之大,所以以后在学习C语言中要更加努力,熟练掌握这门语言,为以后得数学学习打下理论基础。相信自己的不断努力,会让自己的编程能力越来越好。