试题四1. 阅读下列函数说明、图和C代码,填入______处的字句。
[说明] 假定用一个整型数组表示一个长整数,数组的每个元素存储长整数的一位数字,则实际的长整数m表示为:
m=a[k]×10
k-2+a[k-1]×10
k-3+…+a[3]×10+a[2]
其中a[1]保存该长整数的位数,a[0]保存该长整数的符号:0表示正数、1表示负数。
运算时先决定符号,再进行绝对值运算。对于绝对值相减情况,总是绝对值较大的减去绝对值较小的,以避免出现不够减情况。注意,不考虑溢出情况,即数组足够大。
[函数] int cmp (int *LA, int *LB);
/*比较长整数LA与LB的绝对值大小*/
/*若LA绝对值较大返回正值,LA较小返回负值,相等则返回0*/
int ADD(int *LA, int *LB, int *LC)
/*计算长整数LA与LB的和,结果存储于LC中*/
/*注意:正数与负数的和相当于正数与负数绝对值的差*/
/*数据有误返回0,正常返回*/
{
if (LA==NULL || LB==NULL || LC=NULL) return 0;
int *pA, *pB, i, N, carry, flag;
flag=LA[0] + LB[0];
switch(flag) {/*根据参与运算的两个数的符号进行不同的操作*/
case 0:
case 2:
LC[0]=LA[0]; /*LA与LB同号,结果符号与LA(LB)相同*/
pA=LA;
pB=LB;
______;
break;
case 1: /*LA与LB异号*/
/*比较两者的绝对值大小,结果符号与较大者相同*/
flag= ______;
if(flag>0) {/*LA较大*/
LC[0]=LA[0];
pA=LA;
pB=LB;
}
else if(flag<0) {/*LB较大*/
LC [0]=LB[0];
pA=LB;
pB=LA;
}
else {/*LA与LB相等*/
LC[0]=0;
LC[1]=0;
return 1;
}
flag=-1;
break;
default:
return 0;
break;
}/*switch*/
/*绝对值相加减*/
/*注意对于减法pA指向较大数,pB指向较小数,不可能出现不够减情况*/
______;
N=LA[1]>LB[1]?LA[1] : LB[1];
for(i=0; i<N; i++) {
if(i>=pA[1]) {/*LA计算完毕*/
carry+=flag * pB[i+2];
}
else if(i>=pB[1]) {/*LB计算完毕*/
carry+=pA[i+2];
}
else {
carry+=pA[i+2]+flag * pB[i+2];
}
LC[i+2]=carry % 10;
carry/=10;
if(______) {/*需要借位,针对减法*/
LC[i+2]+=10;
carry--;
}
}/*for*/
if(______) {/*最高进位,针对加法*/
LC[i+2]=carry;
i++;
}
if(LC[i+1]==0) i--; /*若最高位为零,针对减法*/
LC[1]=i;
return 1;
}; /*ADD*/
flag=1
cmp(LA,LB)
carry=0
LC[i+2]<0
carry
[解析] 先来看第二个空,依据注释此处是比较LA与LB绝对值的大小,参照cmp函数说咀及声明,应填cmp(LA,LB)。
第三个空以下进行绝对值相加减。carry+=pA[i+2]+flag*pB[i+2];可见,cany需要进行初始化,故第三个空应填carry=0。仔细分析该计算式,可知flag是符号,flag为1时,计算pA+pB,flag为-1时,计算pA-pB。由此也推断出第一个空应填flag=1。case 1中亦有对应语句flag=-1可得验证。
由注释可见第四个空要填的是需要借位的条件。当不够减时需要向高一位借位,也就是不借位时相减结果是负数。因应填LC[i+2]<0。
同第四个空,第五个空要填需要有最高进位的条件。carry变量表示的就是进位。因此第五个空应填carry(或carry!=0)。注此处carry是不可能为负数。
试题五1. 阅读下列函数说明和C++代码,填入______处的字句。
[说明] 在某些系统中,存在非常复杂的对象,可以采用循序渐进的方式进行组合,将小对象组合成复杂的大对象。
以下实例展示了Builder(生成器)模式。该实例用来建立“文件”,文件内容包括:一个标题、一串字符以及一些有项目符号的项目。Builder类规定组成文件的方法,Director类利用这个方法产生一份具体的文件。下图中显示了各个类间的关系。

以下是C++语言实现,能够正确编译通过。
[C++代码] class Buiider {
public:
virtual void makeTitie (string title) =0;
virtual void makeString (String str) =0;
virtual void makeItems (______ items) =0;
virtual string getResult( )=0;
};
class Director {
private:
______ builder;
public:
Director(Buiider *buiider) {
this->builder=buiider;
}
string construct( ) {
vector<string> items;
items.push_back("早安"); items.push_back("午安");
builder->makeTitle("Greeting");
builder->makestring("从早上到白天结束");
builder->makeItems(items);
builder->makestring("到了晚上");
______; //清空items向量
items.push back("晚安"); items.push_back("好梦");
builder->makeItems(items);
return builder->getResult( );
}
};
class TextBuilder : public ______ {
private:
string buffer;
public:
TextBuilder( ) {
buffer="";
}
void makeTitle (String title) {
buffer +="=======================================\n";
buffer +="『" + title + "』 \n";
buffer +="\n";
}
void makeString (String str) {
buffer +="■" + str + "\n";
buffer +="\n";
}
void makeItems(vector<string>items) {
vector<string>::iterator it;
for(it=items.begin( ); it!=items.end( ); it++) {
buffer +="·" + *it + "\n";
}
buffer += "\n";
}
string getResult( ) {
buffer += "========================\n";
return buffer;
}
};
int main( )
{
Director *director=new Director(new TextBuilder( ));
string result=(string)director->______;
cout<<result;
return 0;
}
vector<string>
Builder*
items.cleat( )
Builder
construct( )
[解析] 首先来看第二个空,由名字可猜想builder是一个Builder类对象,由构造函数中的语句this->builder=builder;及形参声NBuilder*builder,可判知第二个空应填Builder*。
由注释可知第三个空是用来清空items向量的,items是一个vector<string>对象,此处并未提供清空方法,应该是调用库函数,故应调用items.clear( )。
现在来看第一个空,由语句builde->makeItems(items);及vector<slring>items;可知,第一个空应填vector<string>。
继续看第四个空,由类图知,TextBuilder是Builder的子类,因此此处应填Builder,声明继承关系。
第五个空是真正进行文件的构造,应填constmct( )。事实上,Director类仅提供了该方法,自然是调用该方法。
2. 阅读以下说明和Java代码,填入______处的字句。
[说明] 在某些系统中,存在非常复杂的对象,可以采用循序渐进的方式进行组合将小对象组合,成复杂的对象。
以下实例展示Builder(生成器)模式。该实例用来建立“文件”,文件内容包括:一个标题、一串字符以及一些有项目符号的项目。Builder类规定组成文件的方法,Director类利用这个方法产生一份具体的文件。下图中显示了各个类间的关系。

以下是Java语言实现,能够正确编译通过。
[Java代码] //Builder.java文件
public ______ class Builder {
public abstract void makeTitle (String title);
public abstract void makeString (String str);
public abstract void makeItems (String[ ]items);
public abstract Object getResult( );
//Director.java文件
public class Director {
private ______ buiider;
public Director (Builder buiider) {
this.builder=builder;
}
public Object construct( ) {
buiider.makeTitle ("Greeting");
buiider.makeString ("从早上到白天结束");
builder.makeltems (new String[ ] ("早安", "午安",));
builder.makeString ("到了晚上");
builder.makeItems (new String[ ] {"晚安", "好梦",});
return builder.getResult( );
}
}
//TextBuilder.java文件
public class TextBuiider ______ Builder {
private StringBuffer buffer=new StringBuffer( );
public void makeTitle (String title) {
buffer.append ("『+title + "』\n\n");
}
public void makeString (String str) {
buffer.append('■'+ str + "\n\n");
}
public void makeItems (String[ ] items) {
for(int i=0; i <______; i++) {
buffer.append ('·' + items[i] + "\n");
}
buffer.append ("\n");
}
public Object getResult( ) {
return buffer.toString( );
}
}
//Main.java文件
public class Main {
public static void main (String[ ] args) {
Director director=new Director (new TextBuilder( ));
String result=(String)director.______;
System.out.println(result);
}
abstract
Builder
extends
items.length
construct( )
[解析] Builder类含有多个abstract方法,故应声明为abstract,第一个空应填abstract。
由构造函数中的语句this.builder=builder;计形参声明Builder builder,可判知第二个空应填Builder。
由类图知,TextBuilder是Builder的子类,因此第三个空应填extends,声明继承关系。
来看第四个空,此处for循环是将items中的对象添加到buffer中,第四个空是循环终止条件:下标达到items的长度,故应填items.length。
第五个空是真正进行文件的构造,应填constmct( )。事实上,Director类仅提供了该方法,自然是调用该方法。
3. 阅读以下函数说明和C代码,填入______处的字句。
[说 明] 在某些系统中,存在非常复杂的对象,可以采用循序渐进的方式,进行组合将小对象组合成复杂的对象。
以下实例展示TBuilder(生成器)模式。该实例用来建立“文件”,文件内容包括:一个标题、一串字符以及一些有项目符号的项目。Builder类规定组成文件的方法,Director类利用这个方法产生一份具体的文件。下图中显示了各个类间的关系。

以下是C语言实现,能够正确编译通过。
[C代码] typedef void (______) (char *title);
typedef void (*fun2) (char items[ ] [10], int N);
typedef char* (*fun3)( );
char buffer[500];
struct Builder {//构造器
fun1 makeTitle;
______ makeString;
fun2 makeItems;
fun3 getResult;
};
struct Director {
struct Buiider buiider;
};
char* construct (______ director)//构造文件
{
char items[2][10]={"早安","午安"};
director->builder.makeTitle("Greeting");
director->builder.makeString("从早上到白天结束");
director->builder.makeItems(items, 2);
director->builder.makeString("到了晚上");
strcpy (items[0], "晚安");
strcpy(items[1], "好梦");
director->builder.makeItems(items, 2);
return director->builder.getResult( );
}
void TXTmakeTitle(char* title)
{
strcat(buffer,"『");
Strcat(buffer, title);
strcat(buffer,"』\n\n");
}
void TXTmakestring(char* str)
{
strcat(buffer, "■");
strcat(buffer,str);
strcat(buffer, "\n\n");
}
void TXTmakeItems(char items[ ][10], int N)//将items加入文件中
{
for(int i=0; i<N; i++) {
strcat(buffer, "·");
strcat(buffer, ______);
strcat(buffer, "\n");
}
strcat(buffer, "\n");
}
char* TXTgetResult( )
{
return buffer;
}
void main( )
{
Director director;
______='\0'; //清空缓冲区,使目前缓冲区中的内容不影响新生成的文件
director.builder.makeTitle=TXTmakeTitle;
director.buiider.makeString=TXTmakeTitle;
director.builder.makeItems=TXTmakeItems;
director.builder.getResult=TXTgetResult;
char* result=construct(&director);
printf("%s\n", result);
}
*fun1
fun1
struct Director*
items[i]
buffer[0]
[解析] 先看第三个空,首先函数construct的形参director应该与Director结构体相关,再根据函数体中的引用方式“director->builder.makeTitle("Greeting");”可知director是一个指针,因此第三个空应填struct Director*。由语句“char* result=construct(&director);”也可进一步确认。
函数TXTmakeItems(char items[ ][10],int N)是将items加入文件中,因此语句strcat(buffer,______);是将第i个items加入缓冲区buffer中,strcat函数的原型为:char*strcat(char *strDestination,const char *strSource);。因此第四个空应填items[i]。
由注释可知语句“buffer[0]=______;”是用来清除缓冲区的,其目的是使目前缓冲区中的内容不影响新生成的文件,就一个语句,事实上不可能清除缓冲区中的所有内容,但纵观生成文件,关键语句就是strcat,这样只要将缓冲区第一个单元的值置为“\0”(字符串结束标志),就能保证正确生成文件。故第五个空应填buffer[0]。