1、初级程序员下午试题-86 及答案解析(总分:105.00,做题时间:90 分钟)一、试题一(总题数:1,分数:15.00)说明为实现图书的国际统一编码,便于实现计算机化的图书管理,每本正式出版的图书都印有国际标准书号。标准书号由“ISBN”、10 个数字(0-9)组成,其格式如下。ISBN 组号-出版者号-书名号-校验码其中,校验码是根据前面 9个数字计算得到的,用于计算机自动校验。假设标准书号的 10个数字依次是a(1),a(2),a(10),则校验码 a(10)的设置应使 S=1O*a(1)+9*a(2)+8*a(3)+1*a(10)能被 11整除。如果校验码 a(10)应设置成 10,则
2、规定以“X”表示之。例如,软件设计师考试考前冲刺预测卷及考点解析的标准书号为:ISBN 7-121-05027-5。第 1段上的数字“7”是国际 ISBN中心分配给中国 ISBN中心管理的组号;第 2段上的“121”表示电子工业出版社。标准书号的校验过程如图 3-16所示,计算校验码的过程如图 3-17所示。其中,Mod(S,11)表示 S除以 11得到的余数。图 3-16 标准书号的校验过程(分数:15.00)_二、试题二(总题数:1,分数:15.00)1.说明打保龄球是用一个滚球去打出 10个站立的柱,将柱击倒。一局分 10轮,每轮可滚球一次或多次,以击倒的柱数为依据计分。一局得分为 10
3、轮得分之和,而每轮的得分不仅与本轮滚球情况有关,还可能与后续一两轮的滚球情况有关。即某轮某次滚球击倒的柱数不仅要计入本轮得分,还可能会计入前一两轮得分。具体的滚球击柱规则和计分方法如下:1) 若某一轮的第一次滚球击倒全部 10个柱,则本轮不再滚球(若是第 10轮则还需另加两次滚球)。该轮得分为本次倒柱数(即 10)与以后两次滚球所击倒柱数之和。2) 若某一轮的第一次滚球未击倒 10个柱,则可对剩下未倒的柱再滚球一次。如果这两次滚球击倒全部10个柱,则本轮不再滚球(若是第 10轮则还需另加一次滚球),该轮得分为本次倒柱数 10与以后一次滚球所击倒柱数之和。3) 若某一轮的两次滚球未击倒全部 10
4、个柱,则本轮不再继续滚球,该轮得分为这两次滚球击倒的柱数之和。总之,若一轮中一次滚球或两次滚球击倒 10个柱,则本轮得分是本轮首次滚球开始的连续 3次滚球击倒柱数之和(其中有一次或两次不是本轮滚球)。若一轮内二次滚球击倒柱数不足 10个,则本轮得分即为这两次击倒柱数之和。表 3-15是打保龄球计分的某个实例说明。表 3-15 某保龄球计分实例表轮 1 2 3 4 5 6 7 8 9 10 附加各轮第 1次得分 10 10 10 7 9 8 8 10 9 10 8各轮第 2次得分 2 1 1 2 1 2各轮得分 30 27 19 9 18 9 20 20 20 20累计总分 30 57 76 8
5、5 103 112 132 152 172 192以下C 程序是模拟打一局保龄球的过程,统计各轮得分和累计总分。程序交互地逐轮逐次输入一次滚球击倒的柱数,计算该轮得分和累计总分。为记录一轮内击倒 10柱,但还暂不能计算该轮得分和累计总分的情况,程序引入变量 ok,用来记录当前已完成完整计算的轮次。程序每输入一次滚球击倒柱数,就检查还未完成完整计算的轮次,并计算。C程序#includestdio.h#define N 13struct int n; /* 一轮内滚球次球 */int f; /* 第一次击倒柱数 */int s; /* 第一次击倒柱数 */int score; /* 本轮得分 */
6、int total; /* 至本轮累计总分 */int m; /* 完成本轮得分计算,还需滚球次数 */aN;int ok = 0; /* 已完成完整计算的轮次数 */int ball(int i, int n, int max) /* 完成一次滚球,输入正确击倒柱数 */int d, j, k;static c=1;while (1)if(i = 10)printf(“ 输入第%d 轮的第%d 次滚球击倒柱数。(=%d)/n“, i, n, max );elseprintf(“ 输入附加的第%d 次滚球击倒柱数。(=%d)/n“, C+, max);scanf(“%d , if (d =0
7、printf(“ 不合理的击倒柱数,请重新输入。/n“)if (ok (1) )/* 对以前未完成计算的轮次分别计算得分与累计总分*/for(j = ok+1; (2) ; j+)aj.score += d;if (-aj.m = 0)aj.total = ( (3) ) + aj.score;ok = (4) ;return d;main ( )int i, first, second, k; /* i表示轮次 */for ( i = 1 ; ok 10 ; i+)ai.score = ai.f = first = ball(i,1,10);if ( first = 10)ai.m = 2;
8、ai.n = 1;if (first 10 if (first + second = 10)ai.m = 1;(6) ;if (i = 10 (7) ;printf( “各轮处 1次得分“);for(k 1; k = 1; k+)printf(“%5d“, ak.f);printf(“/n 各轮第 2次得分“);for(k=1; k = i; k+)if (ak.n 2)printf(“ /“);elseprintf(“%5d“, ak.s);printf(“/n 各轮得分“);for(k = 1; k = ok; k+)printf(“%5d“, ak.score);printf(“/n 累
9、计总分“);for(k = 1; k = ok; k+)printf(“%5d“, ak.total);printf(“/n“);(分数:15.00)_三、试题三(总题数:1,分数:15.00)2.说明以下C 程序所完成的功能是在 3X3方格中填入数字 1N(N10)内的某 9个互不相同的整数,使所有相邻两个方格内的两个整数之和为质数。系统输出满足该要求的所有填法。系统的部分输出结果如图 3-18所示。(分数:15.00)_四、试题四(总题数:1,分数:15.00)3.说明函数 DelA - InsB ( LinkedList La, LinkedList Lb, int key 1,int
10、key 2,int len)的功能是,将线性表 A中关键码为 key 1的节点开始的 len个节点,按原顺序移至线性表 B中关键码为 key 2的节点之前。若移动成功,则返回 0;否则返回-1。线性表的存储结构为带头节点的单链表,La 为表 A的头指针,Lb 为表 B的头指针。单链表节点的类型定义如下。typedef struct nodeint key;struct node*next;*LinkedList;C程序int DelA_InsB (LinkedLiSt La, LinkedList Lb, int key1,int key2,int lenLinkedList p, q, S,
11、 prep, pres;int k;if (!La -next | !Lb -next | len=0)return-l;p = La-next;prep = La;while (p p = p-next;if (!p)return -1; /* 表 A中不存在键值为 key1的节点 */q = p;k = 1;while (q k+;if (!q)return -1; /* 表 A中不存在要被删除的 len个节点 */S = Lb -next;(3) ;while (s s = e-next;if (!s)return -1; /* 表 B中不存在键值为 key2的节点 */(4) q-ne
12、xt; /* 将表 A中的 len个节点删除 */q-next= (5) pres-next = p; /* 将 len个节点移至表 B */return 0;(分数:15.00)_五、试题五(总题数:1,分数:15.00)说明某文件管理系统的图片浏览器如图 3-19所示。运行程序时,用户只要通过驱动器列表框、目录列表框和文件列表框,选择文本文件所在的驱动器、文件夹及相应的文件名后,在图像框中将显示出相应的文件图像。在开发过程中,假设驱动器列表框名为 drvFile,目录列表框名为 dirFile,文件列表框名为 filFile,选择文件类型组合框名为 cboFile,图像框名为 imgSho
13、w。(分数:15.00)_六、试题六(总题数:1,分数:15.00)4.说明C+语言本身不提供对数组下标越界的判断。为了解决这一问题,在以下C+程序中定义了相应的类模板,使得对于任意类型的二维数组,可以在访问数组元素的同时,对行下标和列下标进行越界判断,并给出相应的提示信息。C+程序#include iostream.htemplate class T class Array;template Class T class ArrayBody friend (1) ;T* tpBody;int iRows,iColumns, iCurrentRow;ArrayBody(int IRsz, int
14、 iCsz) tpBody = (2) ;iRows = iRsz;iColumns = iCsz;iCurrentRow = -1;Public:Trow_error = column_error =false;try if (iCurrentRow 0 | iCurrentRow = iRows)row_error = true;if (j0 | j= iColumns)column_error = true;if (row_error = true | column_error = true)(3) ;catch(char)if (row_error = true)cerr “行下标越界
15、“ iCurrentRow “;if (column_error = true)cerr “列下标越界“ j “;cout “/n“;return tpBodyiCurrentRow * iColumns + j;Arraygody()deletetpBody;template class T class Array ArrayBodyT tBody;Public;ArrayBodyT return tBody;Array(int iRsz, int iCsz) : (5) ;void main()Arrayint a1(10,20);Arraydouble a2(3,5);int b1;do
16、uble b2;b1 = a1-510; /有越界提示:行下标越界-5b1 = a11015; /有越界提示:行下标越界10b1 = a114; /没有越界提示b2 = a226; /有越界提示:列下标越界6b2 = a21020; /有越界提示:行下标越界10列下标越界20b2 = a214; /没有越界提示(分数:15.00)_七、试题七(总题数:1,分数:15.00)5.说明某订单管理系统的部分 UML类图如图 3-21所示。(分数:15.00)_初级程序员下午试题-86 答案解析(总分:105.00,做题时间:90 分钟)一、试题一(总题数:1,分数:15.00)说明为实现图书的国际统
17、一编码,便于实现计算机化的图书管理,每本正式出版的图书都印有国际标准书号。标准书号由“ISBN”、10 个数字(0-9)组成,其格式如下。ISBN 组号-出版者号-书名号-校验码其中,校验码是根据前面 9个数字计算得到的,用于计算机自动校验。假设标准书号的 10个数字依次是a(1),a(2),a(10),则校验码 a(10)的设置应使 S=1O*a(1)+9*a(2)+8*a(3)+1*a(10)能被 11整除。如果校验码 a(10)应设置成 10,则规定以“X”表示之。例如,软件设计师考试考前冲刺预测卷及考点解析的标准书号为:ISBN 7-121-05027-5。第 1段上的数字“7”是国际
18、 ISBN中心分配给中国 ISBN中心管理的组号;第 2段上的“121”表示电子工业出版社。标准书号的校验过程如图 3-16所示,计算校验码的过程如图 3-17所示。其中,Mod(S,11)表示 S除以 11得到的余数。图 3-16 标准书号的校验过程(分数:15.00)_正确答案:(制订标准书号的目的是实现图书的国际统一编码,以便于实现计算机化的图书管理,使出版社内的医书管理、书库中的图书管理及书店的图书销售管理具有更高的工作效率和管理水平。标准书号由“ISBN”, 10 个数字(0-9)组成,采用“ISBN 组号出版者号书名号校验码”的格式。其中,出版者号规定为 2-7 位数字。对较大的出
19、版社分配比较短的码,留出较长的书名号为更多的书进行编码。标准书号的最后一位是校验码。设置校验码可以大大减少录入错误造成的管理混乱。校验码一般由计算机程序产生。当操作人员录入前 9个数字后,计算机就会自动启动计算校验码的过程,输出正确的校验码。在书店(或书库),不论是建库还是查询检索,在手工输入带校验码的标准书号后,计算机就会自动启动校验过程,判断是否输入错误。在图 3-17计算校验码的过程中,首先要计算部分 S值,即 S=10*a(1)十 9*a(2)+8*a(3)+2*a (9)。此时需要使用循环处理。在循环开始之前,应设置初始值 S=0。在循环体内,应执行语句“S+=(11-I) *a(I
20、)”或“S+=(1+I)*a(10-I)”(注意,其中的乘号“*”不要丢失)。该循环应对循环变量 I=19 进行(步长默认为 1)控制,因此,(2)空缺处应填入“9”,(3)空缺处所填写的内容是“S+(11-I)*aI-S”或“S+(1+I)*a(10-I)-S”。接着再计算该 S值除以 11的余数 R。显然 0R10。 由于“校验码 a(10)的设置应使 S=10*a(1)+9*a(2)+8*a(3)+1*a(10)能被 11整除”,即余数 R与校验码之和应能被 11整除,因此校验码应等于 MOD(11-R,11),即(4)空缺处所填写的内容是“MOD(11-R,11)”。若读者在该空缺处填
21、写“MOD(11-R)”,则是没有考虑 R=0这一情况。当校验码等于 10时,还应以符号表示。在对标准书号的校验过程(图 3-16)中,首先要将校验码为的情况转换成数据 10,以便于后续计算。为了计算 S=10*a(1)+9*a(2)+8*a(3)+1*a(10),需要使用循环处理。在循环开始之前,应设置初始值S=0,循环变量 I从 1到 10(步长默认为 1)。在循环体内,应执行语句“S+(11-I)*a(1)”或“S+I*a(11 -I)”。因此(1)空缺处所填写的内容是“(11-I)*a(I)”或“I*a(11-I)”。在图 3-16中,计算出 S值之后,还应判断 S除以 11的余数是否
22、为 0。若余数为 0,说明 S能够被 11整除,表示校验结果正确;若余数不为 0,则说明输入的标准书号有错(可能是校验码输入有错,也可能是前面的数字输入有错)。此时计算机应输出相应的错误提示信息,提醒信息录入人员仔细校对改正。)解析:_正确答案:(不使用求余计算符号“%”,求取被除数 p和除数 q之间的余数的 C程序如下。C程序 1static Int fun_Mod(int p,int q) int x=0;while (x=p) if (x = p)return 0;X += q;return q-(x-p);C程序 2int fun_Mod(int p,int q) while(pq)
23、if (x = p)return 0;p -= q;return p;)解析:_正确答案:(由题干说明可知,校验码可以是 09 的数宁或者是符号“”。软件设计师考试考前冲刺预测卷及考点解析的标准书号为:ISBN7-121-05027-5。该标准书号的校验过程如下。余数为 0,说明输入的标准书号正确。结合问题 1要点解析思路,若应试捷径典型考题解析与考点贯通(系统分析师考试)书籍标准书号前 9个数字为 7-121-04715,则其对应的校验码 a(10)的计算过程如下。1) S1=1Oa(1)+9a(2)+8a(3)+7a(4)+6a(5)+5a(6)+4a(7)+3a(8)+2a(9)=107
24、+91+82+71+60+54+47+31+25=1632) 由于 )解析:二、试题二(总题数:1,分数:15.00)1.说明打保龄球是用一个滚球去打出 10个站立的柱,将柱击倒。一局分 10轮,每轮可滚球一次或多次,以击倒的柱数为依据计分。一局得分为 10轮得分之和,而每轮的得分不仅与本轮滚球情况有关,还可能与后续一两轮的滚球情况有关。即某轮某次滚球击倒的柱数不仅要计入本轮得分,还可能会计入前一两轮得分。具体的滚球击柱规则和计分方法如下:1) 若某一轮的第一次滚球击倒全部 10个柱,则本轮不再滚球(若是第 10轮则还需另加两次滚球)。该轮得分为本次倒柱数(即 10)与以后两次滚球所击倒柱数之
25、和。2) 若某一轮的第一次滚球未击倒 10个柱,则可对剩下未倒的柱再滚球一次。如果这两次滚球击倒全部10个柱,则本轮不再滚球(若是第 10轮则还需另加一次滚球),该轮得分为本次倒柱数 10与以后一次滚球所击倒柱数之和。3) 若某一轮的两次滚球未击倒全部 10个柱,则本轮不再继续滚球,该轮得分为这两次滚球击倒的柱数之和。总之,若一轮中一次滚球或两次滚球击倒 10个柱,则本轮得分是本轮首次滚球开始的连续 3次滚球击倒柱数之和(其中有一次或两次不是本轮滚球)。若一轮内二次滚球击倒柱数不足 10个,则本轮得分即为这两次击倒柱数之和。表 3-15是打保龄球计分的某个实例说明。表 3-15 某保龄球计分实
26、例表轮 1 2 3 4 5 6 7 8 9 10 附加各轮第 1次得分 10 10 10 7 9 8 8 10 9 10 8各轮第 2次得分 2 1 1 2 1 2各轮得分 30 27 19 9 18 9 20 20 20 20累计总分 30 57 76 85 103 112 132 152 172 192以下C 程序是模拟打一局保龄球的过程,统计各轮得分和累计总分。程序交互地逐轮逐次输入一次滚球击倒的柱数,计算该轮得分和累计总分。为记录一轮内击倒 10柱,但还暂不能计算该轮得分和累计总分的情况,程序引入变量 ok,用来记录当前已完成完整计算的轮次。程序每输入一次滚球击倒柱数,就检查还未完成完
27、整计算的轮次,并计算。C程序#includestdio.h#define N 13struct int n; /* 一轮内滚球次球 */int f; /* 第一次击倒柱数 */int s; /* 第一次击倒柱数 */int score; /* 本轮得分 */int total; /* 至本轮累计总分 */int m; /* 完成本轮得分计算,还需滚球次数 */aN;int ok = 0; /* 已完成完整计算的轮次数 */int ball(int i, int n, int max) /* 完成一次滚球,输入正确击倒柱数 */int d, j, k;static c=1;while (1)if
28、(i = 10)printf(“ 输入第%d 轮的第%d 次滚球击倒柱数。(=%d)/n“, i, n, max );elseprintf(“ 输入附加的第%d 次滚球击倒柱数。(=%d)/n“, C+, max);scanf(“%d , if (d =0 printf(“ 不合理的击倒柱数,请重新输入。/n“)if (ok (1) )/* 对以前未完成计算的轮次分别计算得分与累计总分*/for(j = ok+1; (2) ; j+)aj.score += d;if (-aj.m = 0)aj.total = ( (3) ) + aj.score;ok = (4) ;return d;main
29、 ( )int i, first, second, k; /* i表示轮次 */for ( i = 1 ; ok 10 ; i+)ai.score = ai.f = first = ball(i,1,10);if ( first = 10)ai.m = 2;ai.n = 1;if (first 10 if (first + second = 10)ai.m = 1;(6) ;if (i = 10 (7) ;printf( “各轮处 1次得分“);for(k 1; k = 1; k+)printf(“%5d“, ak.f);printf(“/n 各轮第 2次得分“);for(k=1; k = i
30、; k+)if (ak.n 2)printf(“ /“);elseprintf(“%5d“, ak.s);printf(“/n 各轮得分“);for(k = 1; k = ok; k+)printf(“%5d“, ak.score);printf(“/n 累计总分“);for(k = 1; k = ok; k+)printf(“%5d“, ak.total);printf(“/n“);(分数:15.00)_正确答案:(阅读题干说明和 C程序可知,该程序由主函数 main和函数 ball组成。其中,函数 ball的功能是输入每轮击倒的柱数并计算以前未完成计算的轮次的得分和累计总分。由于变量 i表
31、示轮次,而变量ok用来记录当前已完成完整计算的轮次,因此(1)空缺处所填写的内容是“i-1”。根据 C程序中的注释信息可知,(2)空缺处所在的 for循环语句是计算以前未完成计算的轮次得分和累计总分,循环控制变量 j的值很显然应小于 i,所以(2)空缺处所填入的内容是“ji”。如果结构体成员 m的值等于 0,则本轮滚球结束,应完成本轮得分计算,同时应累计总分。结构体成员total表示总分,由于它没有赋初值,当 j等于 1时应等于 0,因此(3)空缺处所填入的内容是“j1? aj-1.total:0”。计算完一轮的得分,变量 ok应加 1,故(4)空缺处所填写的内容是“ok+1”。在主函数 ma
32、in中,(5)空缺处所在的语句为计算第 2次滚球的得分,此时应加上第 1次滚球的得分,因此(5)空缺处所填写的内容是“ai.score+=ai.s”。如果两次滚球数等于 10,则 m=1,而 n应加 1,故(6)空缺处所填入的内容为“ai.n+”。(7)空缺处所在的 if语句处理所给规则和记分方法的第 3种情况,即本轮不再滚球,该轮得分为这两次滚球击倒的柱数之和,本次计算完毕,因此(7)空缺处所填写的内容是为“ok=i”。)解析:三、试题三(总题数:1,分数:15.00)2.说明以下C 程序所完成的功能是在 3X3方格中填入数字 1N(N10)内的某 9个互不相同的整数,使所有相邻两个方格内的
33、两个整数之和为质数。系统输出满足该要求的所有填法。系统的部分输出结果如图 3-18所示。(分数:15.00)_正确答案:(无论从程序规模还是从问题的复杂程度上看,这是一道有一定难度的试题。解题时可以先分析题干说明,然后再从程序的结构入手。结合试题说明及在程序中的使用情况,可以确定以下各个变量的含义,以及各个函数的功能。1) bN+1存储可选择的整数的状态,若其值为 1则表示未被选中,可以选;若其值为 0则表示已被选中,不可再选。2) pos记录当前正在处理的方格的位置。3) 数组 checkMatrix3中每个元素的含义是,每个非负整数表示在填入某个位置时需要检查的方格;“-1”表示一个方格的
34、关联方格罗列结束。4) 在函数 find()中使用了变量 ok,从语句“ok=check()”,以及“if(ok)”可知,该变量表示一次check()的成功。5) 从函数的内容上看,函数 write()是打印一个合理的填写方法。6) 函数 isPrime()是判断一个整数是否为质数。7) 函数 selectNum()是为当前方格选择个整数,至于该整数是否合理,还有待函数 check()检查。解题时,不妨再从函数 find()读起。if ( (7) ) write(a);change();由题干说明中的关键信息“直至序号为 8的方格也填入合理的整数后,就找到了一个解,将该解输出,并调整序号为 8
35、的方格所填整数,继续去找下一个解”可知,(7)空缺处所在的 if.else处理语句是上述自然描述语言的表达形式。(7)空缺处所填写的内容就是判断当前填好的方格的位置是否为 8,因此可以填入“pos=8”,也可以填写“pop7”,或者其他等价的语句形式。对于函数 check(), 该函数是检查填入的整数是否合理,从“(j= (1) )=0”和“if(isPrime(apos+aj)”两个语句来看,变量 j在(1)空缺处取得了方格 pos的一个相关位置的位置值。方格 pos的一个相关位置如何取得呢?可以通过取数组 checkMatrix的一个元素来获取。获取时可以通过变量 i来计数,使用“chec
36、kMatrixposi”来依次取得方格 pos的每一个相关位置的值,即(1)空缺处所填写的内容是“checkMatrixposi”。由于函数 isPrime()在 m为质数时返回值为 1,否则返回值为 0,由此可以判断,(2)空缺处所在的语句是在检查到不合理的情况时的处理,即对检查到不合理的情况时的返回处理。如果(2)、(3)空缺处所在的for循环能够顺利结束,则说明检查结果是合理的,即该填写的内容是合理的。此时也应该进行返回处理,即(3)空缺处所在的语句也是一个返回控制。由于函数 check()需要一个返回值以表明检查结果,其中,返回非 0的值表示成功,否则即为失败(这从函数 find()中
37、 if(ok)与 ok=check()两条语句也可以看出),因此(2)空缺处所填写的内容是“return0”或“return j0?1:0”,(3)空缺处所填写的内容是“return 1”或“return j0?1:0”。(4)空缺处所在的 extend()函数中,由于在调用该函数时指针 pos仍然指向当前方格,因此在为下一个方格 pos寻找尚未使用的整数时,首先必须是指针 pos加 1,使之指向下一个方格。另外,(4)空缺处之后有“bapos=0”的操作,结合对函数 selectNum()的理解可知,这是将已经选用过的整数在 bN+1的相应响应位置 0。这也间接要求(4)空缺处所进行的操作还
38、必须改变 pos的值,因此,(4)空缺处所填写的内容是“+pos”。从函数 change()的整体结构可以看出,这是个回溯处理过程。如果回溯到“posO”时,回溯处理过程就结束;否则选中 j为位置 pos的值。那么这个回溯过程是怎样实现的呢?函数 change()是通过 while循环来实现。(5)空缺处是构造函数 selectNum()的 start的值,由于在选 apos时已经从 1开始搜寻了,apos之前的值显然不必再搜寻了,且 apos也被证明不合适,因此 start的值只需从 apos+1开始,即(5)空缺处所填写的内容是“apos+1”,而不是“+apos”或者“apos+”。当函
39、数 change()的 while循环条件成立时,需要进行回退处理。此时先前已经被选中的整数不再有效,应恢复 bN+1中相应位置的元素值,并将该元素值置 1(表示未被选中)。考虑到需要修改 pos以适应下一次对换,因此(6)空缺处所填写的内容是“bapos-=1”,而不是“bapos-1=1”。)解析:四、试题四(总题数:1,分数:15.00)3.说明函数 DelA - InsB ( LinkedList La, LinkedList Lb, int key 1,int key 2,int len)的功能是,将线性表 A中关键码为 key 1的节点开始的 len个节点,按原顺序移至线性表 B中
40、关键码为 key 2的节点之前。若移动成功,则返回 0;否则返回-1。线性表的存储结构为带头节点的单链表,La 为表 A的头指针,Lb 为表 B的头指针。单链表节点的类型定义如下。typedef struct nodeint key;struct node*next;*LinkedList;C程序int DelA_InsB (LinkedLiSt La, LinkedList Lb, int key1,int key2,int lenLinkedList p, q, S, prep, pres;int k;if (!La -next | !Lb -next | len=0)return-l;p
41、 = La-next;prep = La;while (p p = p-next;if (!p)return -1; /* 表 A中不存在键值为 key1的节点 */q = p;k = 1;while (q k+;if (!q)return -1; /* 表 A中不存在要被删除的 len个节点 */S = Lb -next;(3) ;while (s s = e-next;if (!s)return -1; /* 表 B中不存在键值为 key2的节点 */(4) q-next; /* 将表 A中的 len个节点删除 */q-next= (5) pres-next = p; /* 将 len个节
42、点移至表 B */return 0;(分数:15.00)_正确答案:(这是一道要求读者在单链表上实现元素的群插入、群删除操作的程序设计题。本题的解答思路如下。本程序是在链表插入和删除单个节点的基础上进行扩展的,一次性插入多个节点和删除多个节点。元素的群插入或群删除操作是在只删除一个元素的基础上,通过增加一个寻找指定大小和指定数量节点的过程来实现的。其原理和插入、删除一个节点的运算是一致的。首先在链表 A中查找键值为 key1的节点。在程序中使用了如下的第 1个 while循环语句。while (p k+;第 2个 while循环是为了找到以键值为 key1的节点开始的 len个节点。若查找成功
43、,指针吁将指向 len个节点中的最后一个节点。程序先将 q指向 p,变量 k是用来计算节点个数的计数器。而该循环的结束条件有两个。第 1个是 p的后面没有 len个节点。此时 q为空,所以(2)空缺处所填写的语句是“q=q-next”或“q=(*q).next”,使 q的指针往后移动。第 2个是 p的后面有 len个节点。此时 k=len,所以(1) 空缺处所填写的语句是“klen”。如果 p的后面有 len个节点,则 q指向第 len个节点,如图 3-22所示。图 3-22 中的虚线表示省略了中间若干个节点。图 3-22 链表示意图 1同理,在链表 B中查找键值为 key2的节点,使用了如下的第 3个 while循环语句。S = L