第六章数组
- 格式:doc
- 大小:389.50 KB
- 文档页数:50
C++程序设计第6章数组单个变量只能存放一个数据值。
当程序中要处理一组相同类型、彼此相关的一组数据时,单个变量就不适合了,就需要一种特殊的数据结构来处理,这就是数组。
数组(array)是一种派生类型。
一个数组能同时存放多个数据值,并能对每个数据进行访问。
本章将介绍一维数组、二维数组和字符数组的定义及使用。
6.1 一维数组一个数组(array)是由相同类型的一组变量组成的一个有序集合。
数组中的每个变量称为一个元素(element),所有元素共用一个变量名,就是数组的名字。
数组中的每个元素都有一个序号,称为下标(index)。
访问一个元素就可以用数组名加下标来实现。
数组必须先定义后使用。
6.1.1 一维数组的定义一维数组就是具有一个下标的数组。
定义一个数组有3个要素:类型、名称与大小。
语法格式为:<数据类型> <数组名> [<常量表达式>]其中,<数据类型>确定了该数组的元素的类型,可以是一种基本数据类型,也可以是已定义的某种数据类型。
<数组名>是一个标识符,作为数组变量的名字。
方括号中的<常量表达式>必须是一个正整型数据,其值为元素的个数,即数组的大小或长度。
注意这里的方括号[]表示数组,而不是表示可缺省内容。
例如,下面定义了三个不同类型的数组:int a[5]; //定义了一个int数组afloat b[20]; //定义了一个float数组bdouble c[5]; //定义了一个double数组c对于上面数组a,元素类型为int,a是数组名,方括号中的10表示数组的长度,即该数组包含了5个元素,分别是a[0]、a[1]、a[2]、a[3]、a[4]。
如果一个数组有n个元素,那么数组中元素的下标从0开始到n-1。
具有相同类型的数组可以在一条说明语句中定义。
例如:int a1[5], a2[4]; //同时定义两个整型数组具有相同类型的单个变量和数组也可以在一条语句中定义。
第六章数组学习和解题要点1.要学习和掌握C语言的数组问题,首先必须形成这么一个观念,当用数组定义语句:[存储类型] 数据类型数组名[长度];定义一个数组时,表明请求计算机在内存开辟一个大的空间,该空间的名字即为数组名,同时数组名也是该空间在内存的起始地址。
空间的大小由“长度”决定,因此“长度”必须是正整常数明确确定。
即使是N,该N也必须在前面的#define N中明确指明是多少。
该空间可放“长度”个同一类型的数据。
放什么样的数据由数据类型指定。
如:int a[10]; 表明内存地址为a 放10个整数,每个小空间为a[0],a[1],……,a[9]a↘2. 有的想用下面的方法定义任意大小的数组:int n;scanf(“%d”,&n);int a[n];认为从键盘输入一多少大整数给n,则就定义多少大的数组。
这也是错误的。
因为C语言规定,执行语句以后,就不能再出现定义语句。
这种根据程序的需要随时申请空间的称为“动态数据结构”,要用以后的结构类型和指针来解决。
3.可在定义数组的同时,马上就赋初值。
也可由初值的个数决定数组的大小。
如:int a[]={1,2,3,4,5,6,7,8,9,10};4.对数值型的数组操作,只能一个元素一个元素的使用,每一的元素的使用都可以看成一个变量的使用,称之为带下标的变量,而决不允许用数组名。
如 a[i] 当i为多少时即为那一个元素。
在程序中要时时注意现在是对那一个元素操作,如在教材中的“冒泡排序法”和“选择排序法”的程序中要注意现在下标是那一个元素。
注意:定义中的int a[10] 表示共10个元素,而程序中的a[10]表示带下标的变量。
5.二维数组的定义与一维一样,必须有二个正整常数明确确定,我们可以看成多少行和多少列个元素,如果在定义数组的同时赋初值,则第一维的长度可以省略。
无论如何,第二维的长度决不能缺省。
6.对数值型的二维数组,也只能一个元素一个元素的使用,这时一定要二个下标,表示那一行那一列的元素。
第6章数组6.1 问题导引与分析到目前为止,我们所接触的变量类型(除文件类型外)为简单数据类型,其特点是对单一的变量进行数据处理和操作。
在解决实际问题时,常需要处理大量的数据,如对1000个学生的成绩排序、对一批数据进行各种处理等问题,如果用简单变量来存储这些数据,要用到大量的简单变量,无论从存储还是处理都很不现实。
Pascal语言引入了数组类型,能方便地解决批量数据处理问题。
数组是程序设计中最常用的结构数据类型,用来描述由固定数目的同一类型的元素组成的数据结构。
从形式上看,Pascal语言数组元素书写格式为:变量名[下标1,下标2,下标3,……],数组的每个元素和下标相关联,根据下标指示数组的元素。
只有一个下标的变量集合称为一维数组。
如:a[1],a[2],a[3],a[4],a[5],……,俗称a数组。
使用数组的方便之处在于数组的下标可以用变量来表示,如上述的a数组元素可以写成a[i]形式,通过灵活控制下标变量i,达到对数组元素进行批量处理和操作的目的。
6.1.1 问题导引问题6.1 选票统计(Votes)【问题描述】国际运动协会组织了一个评选N佳运动员的活动,评选方式很特殊,先由网民投票选举,各国的网民可以任选自己喜爱的运动员,然后从中选出得票高于100万张的运动员N个,对他们用1到N进行编号,重新投票,根据不同的得票值,颁发不同的奖项,现在组织者想知道重新投票后,这N个运动员的票数,请你帮他完成。
【输入格式】第一行,一个数,表示N个运动员;(1≤N≤1000)第二行开始为一组以空格隔开的选票,选票值为1到N间的数,以-1为数据结束标志。
选票数量不超出长型范围。
【输出格式】按编号顺序输出编号和票数。
【输入样例】33 1 2 3 2 1 2 3 1 2 2 1 3 3 1 2 3 3 -1【输出样例】1 52 63 7问题6.2 质数(prime.pas)【问题描述】求1到N间的质数。
【输入格式】一个数N。
(1<N<1000000)【输出格式】以空格隔开的质数。
【输入样例】10【输出样例】2 3 5 7问题6.3 查找(Find)【问题描述】中考成绩出来了,许多考生想知道自己成绩排名情况,于是考试委员会找到了你,让你帮助完成一个成绩查找程序,考生只要输入成绩,即可知道其排名及同名次的人有多少。
【输入格式】第一行一个数N;第二行一个数K;第三行开始N个以空格隔开的从大到小排列的所有学生中考成绩。
接着K个待查找的考生成绩。
【输出格式】K行,每行为一个待查找的考生的名次、同名次的人数、比考生高分的人数。
查找不到输出“fail!”。
【输入样例】102580 570 565 564 564 534 534 534 520 520564 520【输出样例】4 2 36 2 86.1.2 问题分析分析问题6.1对于选票统计问题,如果用人工来统计会是如何统计呢?通常的一种方法是,先写上每个人选的标识符,如:本题中用编号标识,然后一边唱票,一边在对应人的标识符的下方打上增加票数的标志,如:用“正”字,每增加一票,增加“正”字的一个笔划,当唱票完毕,统计一下每个人选得到的“正”字的笔划数即为每个人选的票数。
然而,本题中,N值可以达到1000,且每人的得票值很大,人工完成统计是不可能的,但人工的统计方法是可以借鉴的,将人工的统计方法转换为算法,描述如下。
算法描述:1.开辟每个人选的票数值存放空间;2.读入参选人数N值;3.读入第一张投票号X;4.当X<>-1时,即读票未结束,反复执行下列操作:(1)对应X号人选的票数加1;(2)读入下一张投票号X;5.当读完投票,输出参选人的票数。
分析问题6.2关于质数判断问题,在第四章的例4.4中做过讨论。
其算法思想基于数学对质数的定义,因此,在例4.4基础上,我们比较容易得到求1~N之间的质数的一种算法,描述如下。
1.读入N;2.输出质数2;3.对3~N间的每个数进行质数判定,为质数的输出。
该算法的时间复杂度为O(n2),当N比较大时,需要一定时间才能出解。
变换角度分析,2是质数,2的倍数一定不是质数,这些数就无需进行质数判定,同理,3是质数,3的倍数一定不是质数,……。
于是,先把N个自然数按次序排列起来,1不是质数,也不是合数,要划去。
第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。
2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。
3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。
这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。
这种按顺序输出质数的同时,将质数的倍数筛去的算法,称为筛法。
用筛法求质数是一种比较快的算法,算法时间复杂度为O(n2)。
这里用到一个名词:算法复杂度。
算法复杂度包括时间复杂度和空间、复杂度,时间复杂度指执行算法所需的时间(执行多少次赋值、比较等操作),空间复杂度指执行算法需要消耗多少存储空间。
算法的时间和空间复杂度是算法设计和选择一个很重要的考量参数。
分析问题6.3由于给出的原始数据是有序的,在读入数据过程中可以得到的有效信息有:1.当读入数与前一个数不同时,名次增1;2.当读入数与前一个数相同时,相同分数人数增1,累计到当前的人数增1。
因此,为了方便后面的查找,先进行预处理,扫描数据,按从大到小的顺序记下每个不同数据的名次、相同人数、累计人数。
在经过预处理后的有序数据中实现查找并输出。
最简单的查找方式为,按顺序查找,找到相同的成绩或找不到后输出。
这种查找方式称之为顺序查找,显然,在数据量比较大的情况下,顺序查找的效率是比较低的。
寻求提高效率算法的突破口之一,充分利用问题给予的条件,本问题中给出了一个非常重要的条件就是,数据是有序的。
这里引入如何在有序数中快速查找数据的算法----二分查找法。
二分查找算法思想:将N个元素分别分成个数大致相同的两半,取中间数a[n/2],如果x=a[n/2],则找到x,算法终止,如果x<a[n/2],则在a[n]的左半部分继续查找x,如果x>a[n/2],则在a[n]的右半部分继续查找,接下去查找的数据范围为上一次数据范围的一半,继续执行此算法。
例:在有序序列[05 13 19 21 37 56 64 75 80 88 92]中查找数据21和85。
[05 13 19 21 37 56 64 75 80 88 92][05 13 21 37] 56 64 75 80 88 9205 13 19 [21 37] 56 64 75 80 88 92查找K=21的过程(查找成功)[05 13 19 21 37 64 75 80 88 92]05 13 19 21 37 56 [64 75 80 88 92]05 13 19 21 37 56 64 75 80 [88 92]05 13 19 21 37 56 64 75 80 [88 92]查找K=85的过程(查找失败)二分查找算法的时间复杂度为O(Log2(N))。
6.1.3 解决方案为实现问题6.1、问题6.2和问题6.3的算法,需要先解决以下几个问题:1.如何定义和存储批量数据;2.如何根据需要直接找到批量数据中的某一个数据。
通过对数组的学习和灵活使用,将有效解决批量数据处理等问题。
6.2 一维数组6.2.1 一维数组的定义当数组中每一个元素只带有一个下标时,称为一维数组。
PASCAL语言中,定义数组可以采用以下几种方式。
1.在说明部分的TYPE区中定义数组类型,然后再在VAR区中说明数组,形式如下:TYPE数组类型标识符=array [下标类型] of 元素类型;下标类型必须是一个顺序类型,其作用是指定数组下标的编制方式和下标取值范围。
基类型规定了数组元素的类型和性质,可以是integer,char,real,boolean等。
例如:TYPEsample=array [1..10]of integer;{有10个元素的一维数组}VARa,b: sample;在说明部分的TYPE区中,由用户定义了一个名为sample的数组类型,在VAR区部分说明了a和b为sample类型的数组。
2.直接在VAR区中定义数组VAR数组名:array [下标类型] of 元素类型;例如:VARa,b: array [1..10]of integer;3.数组的常量定义CONST数组名:array [下标类型] of 元素类型=(逗号隔开的数据);逗号隔开的数据个数要与下标类型定义数组元素个数相一致。
数据类型和元素类型相一致.(1)consta:array[1..3] of integer=(3,4,5);(2)constHexadecimal : array[0..15] of char =(‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’);或者:Hexadecimal : array[0..15] of char = ‘0123456789ABCDEF’;当在说明部分定义了一个数组之后,PASCAL编译程序为所定义的数组在内存空间开辟一串连续的存储单元。
例如:TYPEcolor=(red,yellow,blue,while,black);rowtype=array[1..8] of real;coltype=array[‘A’..’E’] of integer;colortype=array[color] of CHAR;VARa: rowtype;b: coltype;c: colortype;以上程序段定义了a、b、c三个数组,它们在内存中的排列如下图示意。
a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8]a数组的存储结构b[‘A’] b[‘B’] b[‘C’] b[‘D’] b[‘E’]b数组的存储结构c[red] c[yellow] c[blue] c[while] c[black]c数组的存储结构6.2.2一维数组的引用当定义了一个数组,数组中的各个元素就共享一个数组名(即为数组变量名),元素之间通过不同的下标进行区别。
对数组的操作归根到底就是对数组元素的操作。
一维数组元素的引用格式为:数组名[下标表达式](1)下标表达式值的类型,必须与数组类型定义中的下标类型完全一致,并且不允许超越所定义的下标上界和下界。
(2)数组是一个整体,数组名是一个整体的标识,对数组进行操作,即对其元素操作。
数组元素可以像同类型的普通变量那样使用。
例如:a[3]:=34; 对数组a中下标值为3的下标变量赋以34的值。