1一、填空题1.不包含任何字符(长度为0)的串称为空串;由一个或多个空格(仅由空格符)组成的串称为空白串。2.设S=“A;/document/Mary.doc”,则strlen(s)=20,“/”的位置为3。3.子串的定位运算称为串的模式匹配;被匹配的主串称为目标串,子串称为模式。4、若n为主串长,m为子串长,则串的古典(朴素)匹配算法最坏的情况下需要比较字符的总次数为(n-m+1)*m。5、假设有二维数组A6×8,每个元素用相邻的6个字节存储,存储器按字节编址。已知A的起始存储位置(基地址)为1000,则数组A的体积(存储量)为288B;末尾元素A57的第一个字节地址为1282;若按行存储时,元素A14的第一个字节地址为(8+4)×6+1000=1072;若按列存储时,元素A47的第一个字节地址为(6×7+4)×6+1000)=1276。(注:数组是从0行0列还是从1行1列计算起呢?由末单元为A57可知,是从0行0列开始!)6、设数组a[1…60,1…70]的基地址为2048,每个元素占2个存储单元,若以列序为主序顺序存储,则元素a[32,58]的存储地址为8950。答:不考虑0行0列,利用列优先公式:LOC(aij)=LOC(ac1,c2)+[(j-c2)*(d1-c1+1)+i-c1)]*L得:LOC(a32,58)=2048+[(58-1)*(60-1+1)+32-1]]*2=89507、三元素组表中的每个结点对应于稀疏矩阵的一个非零元素,它包含有三个数据项,分别表示该元素的行下标、列下标和元素值。8、二维数组A[10][20]采用列序为主方式存储,每个元素占10个存储单元,且A[0][0]的存储地址是2000,则A[6][12]的地址是32609、已知二维数组A[20][10]采用行序为主方式存储,每个元素占2个存储单元,并且A[10][5]的存储地址是1000,则A[18][9]的存储地址是116810、广义表((a,b),c,d)的表头是(a,b),表尾是(c,d)11、广义表((((a),b),c),d)的表头是(((a),b),c),表尾是(d)12、已知二维数组A[10][20]采用行序为主方式存储,每个元素占2个存储单元,并且A[0][0]的存储地址是1024,则A[6][18]的地址是130013、若串的长度不能确定,可采用动态存储结构,为串值分配一个存储空间,同时建立一个串的描述子以指示串值的长度和串在存储空间中的位置,称该结构为堆/堆结构14、稀疏矩阵一般的压缩存储方法有两种,即三元组表和十字链表。二、单选题1、串是一种特殊的线性表,其特殊性体现在(B)A.可以顺序存储B.数据元素是一个字符C.可以链式存储D.数据元素可以是多个字符2、设有两个串p和q,求q在p中首次出现的位置的运算称作(B)A.连接B.模式匹配C.求子串D.求串长23.设串s1=’ABCDEFG’,s2=’PQRST’,函数con(x,y)返回x和y串的连接串,subs(s,i,j)返回串s的从序号i开始的j个字符组成的子串,len(s)返回串s的长度,则con(subs(s1,2,len(s2)),subs(s1,len(s2),2))的结果串是(D)A.BCDEFB.BCDEFGC.BCPQRSTD.BCDEFEF解:con(x,y)返回x和y串的连接串,即con(x,y)=‘ABCDEFGPQRST’;subs(s,i,j)返回串s的从序号i开始的j个字符组成的子串,则subs(s1,2,len(s2))=subs(s1,2,5)=’BCDEF’;subs(s1,len(s2),2)=subs(s1,5,2)=’EF’;所以con(subs(s1,2,len(s2)),subs(s1,len(s2),2))=con(’BCDEF’,’EF’)之连接,即BCDEFEF4.假设有60行70列的二维数组a[1…60,1…70]以列序为主序顺序存储,其基地址为10000,每个元素占2个存储单元,那么第32行第58列的元素a[32,58]的存储地址为(A)。(无第0行第0列元素)A.16902B.16904C.14454D.答案A,B,C均不对答:此题与填空题第8小题相似。(57列×60行+31行)×2字节+10000=169025.设矩阵A是一个对称矩阵,为了节省存储,将其下三角部分(如下图所示)按行序存放在一维数组B[1,n(n-1)/2]中,对下三角部分中任一元素ai,j(i≤j),在一维数组B中下标k的值是(B)A.i(i-1)/2+j-1B.i(i-1)/2+jC.i(i+1)/2+j-1D.i(i+1)/2+j6.从供选择的答案中,选出应填入下面叙述?内的最确切的解答,把相应编号写在答卷的对应栏内。有一个二维数组A,行下标的范围是0到8,列下标的范围是1到5,每个数组元素用相邻的4个字节存储。存储器按字节编址。假设存储数组元素A[0,1]的第一个字节的地址是0。存储数组A的最后一个元素的第一个字节的地址是A。若按行存储,则A[3,5]和A[5,3]的第一个字节的地址分别是B和C。若按列存储,则A[7,1]和A[2,4]的第一个字节的地址分别是D和E。供选择的答案:A~E:①28②44③76④92⑤108⑥116⑦132⑧176⑨184⑩188答案:ABCDE=8,3,5,1,67.有一个二维数组A,行下标的范围是1到6,列下标的范围是0到7,每个数组元素用相邻的6个字节存储,存储器按字节编址。那么,这个数组的体积是A个字节。假设存储数组元素A[1,0]的第一个字节的地址是0,则存储数组A的最后一个元素的第一个字节的地址是B。若按行存储,则A[2,4]的第一个字节的地址是C。若按列存解:注意B的下标要求从1开始。先用第一个元素去套用,可能有B和C;再用第二个元素去套用B和C,B=2而C=3(不符);所以选BnnnnaaaaaaA,2,1,2,21,21,13储,则A[5,7]的第一个字节的地址是D。供选择的答案:A~D:①12②66③72④96⑤114⑥120⑦156⑧234⑨276⑩282(11)283(12)288答案:ABCD=12,10,3,98、以下关于广义表的叙述中,正确的是(A)A)广义表是由0个或多个单元素或子表构成的有限序列B)广义表至少有一个元素是子表C)广义表不能递归定义D)广义表不能为空表三、简答题1.已知二维数组Am,m采用按行优先顺序存放,每个元素占K个存储单元,并且第一个元素的存储地址为Loc(a11),请写出求Loc(aij)的计算公式。如果采用列优先顺序存放呢?解:公式教材已给出,此处虽是方阵,但行列公式仍不相同;按行存储的元素地址公式是:Loc(aij)=Loc(a11)+[(i-1)*m+(j-1)]*K按列存储的元素地址公式是:Loc(aij)=Loc(a11)+[(j-1)*m+(i-1)]*K2.递归算法比非递归算法花费更多的时间,对吗?为什么?答:不一定。时间复杂度与样本个数n有关,是指最深层的执行语句耗费时间,而递归算法与非递归算法在最深层的语句执行上是没有区别的,循环的次数也没有太大差异。仅仅是确定循环是否继续的方式不同,递归用栈隐含循环次数,非递归用循环变量来显示循环次数而已。四、判断题1、(√)子串是主串中任意个连续字符组成的序列。2、(√)广义表(((a),b),c)的表头是((a),b),表尾是(c)。3、(×)数组元素的下标值越大,存取时间越长4、(×)长度为1的串等价于一个字符型常量⒋(×)设有两个串p和q,求q在p中首次出现的位置的运算称作求子串。⒌(√)二维数组是其数据元素为线性表的线性表。6、(╳)若采用三元组压缩技术存储稀疏矩阵,只要把每个元素的行下标和列下标互换,就完成了对该矩阵的转置。7、(╳)若一个广义表的表头为空表,则此广义表亦为空表。8、(╳)用一维数组存储二叉树时,总是以前序遍历存储节点。五、计算题1.设s=’IAMASTUDENT’,t=’GOOD’,q=’WORKER’,求Replace(s,’STUDENT’,q)和Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))。解:①Replace(s,’STUDENT’,q)=’IAMAWORKER’②因为SubString(s,6,2)=‘A’;SubString(s,7,8)=‘STUDENT’Concat(t,SubString(s,7,8))=’GOODSTUDENT’所以Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))=‘AGOODSTUDENT’42.用三元组表表示下列稀疏矩阵:2000000000000005000000000006000000000000030008000000000000000000)1(000003000000000500000000000009200000)2(解:参见填空题4.三元素组表中的每个结点对应于稀疏矩阵的一个非零元素,它包含有三个数据项,分别表示该元素的行下标、列下标和元素值。所以(1)可列表为:(2)可列表为:8853233685467858123.下列各三元组表分别表示一个稀疏矩阵,试写出它们的稀疏矩阵。16166354443131212221646)1(734653823942111554)2(解:(1)为6×4矩阵,非零元素有6个。(2)为4×5矩阵,非零元素有5个六、算法设计题(每题10分,共30分)1.编写一个实现串的置换操作Replace(&S,T,V)的算法。解:intReplace(Stringtype&S,StringtypeT,StringtypeV);//将串S中所有子串T替66416-225943565302001200030000004006016000100000009008006007005换为V,并返回置换次数{for(n=0,i=1;i=Strlen(S)-Strlen(T)+1;i++)//注意i的取值范围if(!StrCompare(SubString(S,i,Strlen(T)),T))//找到了与T匹配的子串{//分别把T的前面和后面部分保存为head和tailStrAssign(head,SubString(S,1,i-1));StrAssign(tail,SubString(S,i+Strlen(T),Strlen(S)-i-Strlen(T)+1));StrAssign(S,Concat(head,V));StrAssign(S,Concat(S,tail));//把head,V,tail连接为新串i+=Strlen(V);//当前指针跳到插入串以后n++;n++;}//ifreturnn;}//Replace分析:i+=Strlen(V);这一句是必需的,也是容易忽略的.如省掉这一句,则在某些情况下,会引起不希望的后果,虽然在大多数情况下没有影响.请思考:设S='place',T='ace',V='face',则省掉i+=Strlen(V);运行时会出现什么结果?2.试设计一个算法,将数组An中的元素A[0]至A[n-1]循环右移k位,并要求只用一个元素大小的附加存储,元素移动或交换次数为O(n)解:分析:要把A的元素循环右移k位,则A[0]移至A[k],A[k]移至A[2k]......直到最终回到A[0].然而这并没有全部解决问题,因为有可能有的元素在此过程中始终没有被访问过,而是被跳了过去.分析可知,当n和k的最大公约数为p时,只要分别以A[0],A[1],...A[p-1]为起点执行上述算法,就可以保证每一个元素都被且仅被右移一次,从而满足题目要求.也就是说,A的所有元