一、问答题
1、阅读以下说明和流程图,填补流程图中的空缺,将解答填入答题纸的对应栏内。
[说明]
下面流程图的功能是:在给定的一个整数序列中查找最长的连续递增子序列。设序列存放在数组A[1:n](n≥2)中,要求寻找最长递增子序列A[K:K+L-1](即A[K]<A[K+1]<…<A[K+L-1])。流程图中,用Kj和Lj分别表示动态子序列的起始下标和长度,最后输出最长递增子序列的起始下标K和长度L。
例如,对于序列A={1,2,4,4,5,6,8,9,4,5,8},将输出K=4,L=5。
[流程图]
注:循环开始框内应给出循环控制变量的初值和终值,默认递增值为1,格式为:循环控制变量=初值,终值
参考答案:
n-1 Lj+1→Lj Lj>L Kj i+1
解析:
本题考查的是理解和绘制程序流程图的能力,特别是在设计算法时,如何在一个整数序列中查找最长的连续递增子序列。查找的方法是从头开始逐个与后面邻接的数进行比较。
一、关于循环开始的部分,由于需要比较A[i]与A[i+1],因此循环应从1到n-1,所以(1)处应填n-1。
二、当A[i]<A[i+1]时,表示发现了连续递增的情况,此时应增加动态连续递增序列的长度,因此(2)处应填写Li+1→Lj。
三、当A[i]<A[i+1]不成立时,表示之前的连续递增已经结束。此时需比较当前的动态长度Li与记录的最大长度L。所以(3)处应填Lj>L。
四、当Lj>L时,表示找到了更长的连续递增子序列,需要更新记录的最大长度和起始下标,因此(4)处应填写Lj→L和Kj→K。
五、当Lj→L不成立时,表示当前子序列并非最长,需要从下一个位置重新开始查找,因此(5)处应填写i+1,并且动态长度Lj需要重置为1。
最后,循环结束后还需要再次比较最后一个动态连续子序列与之前的记录,以确保找到的最长连续递增子序列是真正的最长序列。
2、阅读以下说明和C代码,填补代码中的空缺,将解答填入答题纸的对应栏内。
[说明]
下面的代码运行时,从键盘输入一个四位数(各位数字互不相同,可以有0),取出组成该四位数的每一位数,重组成由这四个数字构成的最大四位数max4和最小四位数min4(有0时为三位数),计算max4与min4的差值,得到一个新的四位数。若该数不等于6174,则重复以上过程,直到得到6174为止。
例如,输入1234,则首先由4321-1234,得到3087;然后由8730-378,得到8352;最后由8532-2358,得到6174。
[C代码] #include<stdio.h> int difference(int a[]) ( int t,i,j,max4,min4; for(i=0; i<3; i++){/*用简单选择排序法将a[0]~a[3]按照从大到小的顺序排列*/ t=i; for(j=i+1; ______; j++) if(a[j]>a[t]) ______; if(t!=i){ int temp=a[t]; a[t]=a[i]; a[i]=temp; } } max4=______; min4=______; return max4-min4; } int main() { int n,a[4]; printf("input a positive four-digit number:"); scanf("%d",&n); while(n!=6174){ a[0]= ______; /*取n的千位数字*/ a[1]=n/100%10; /*取n的百位数字*/ a[2]=n/10%10; /*取n的十位数字*/ a[3]= ______; //取n的个位数字*/ n=difference(a); } return 0; }
参考答案:
j<4或等价形式 t=j a[0]*1000+a[1]*100+a[2]*10+a[3] 或等价形式 a[3]*1000+a[2]*100+a[1]*10+a[0] 或等价形式 n/1000 或等价形式 n%10
解析:
本题考查C程序设计中的数组操作、选择排序算法以及位运算。
首先,从主函数main开始,需要输入一个四位数,并通过数组a存储每一位数字。空5和空6分别用于获取这个四位数的千位和个位数字,通过除以10的幂次和模运算可以得到。例如,空5处填写的表达式“n/1000”可以获取千位数字。同理,空6处填写的表达式“n%10”可以获取个位数字。这两个表达式都是获取数组中每个元素(代表数字的每一位)的标准方法。
接下来是函数difference的实现。该函数的主要目的是对一个包含四个数字的数组进行排序,然后计算最大数和最小数的差值。空1和空2是关于选择排序的填充部分。在选择排序中,我们需要遍历整个数组以找到最大值的索引。因此,空1处应填写“j<4”或任何确保循环在数组长度内的等价条件。当找到更大的数字时,我们需要更新最大值的索引,所以空2处填写“t=j”。
最后,计算最大数和最小数的和,即max4和min4。由于数组已经排序,最大数在a[0],最小数在a[3](如果最小数前有零,则为a[2])。因此,空3和空4分别表示max4和min4的计算方式。将排序后的数组元素按照位数相乘并相加,即可得到最大数和最小数。例如,“a[0]*1000+a[1]*100+a[2]*10+a[3]”表示将排好序的数组元素组合成最大的四位数。同理,“a[3]*1000+a[2]*100+a[1]*10+a[0]”表示组合成最小的四位数(如果有前导零则为三位数)。
3、阅读以下说明和C代码,填补代码中的空缺,将解答填入答题纸的对应栏内。
[说明]
对一个整数序列进行快速排序的方法是:在待排序的整数序列中取第一个数作为基准值,然后根据基准值进行划分,从而将待排序列划分为不大于基准值者(称为左子序列)和大于基准值者(称为右子序列),然后再对左子序列和右子序列分别进行快速排序,最终得到非递减的有序序列。
函数quicksort(int a[],int n)实现了快速排序,其中,n个整数构成的待排序列保存在数组元素a[0]~a[n-1]中。
[C代码] #inclLade<stdi0.h> void quicksort(int a[], int n) { int i,j; int pivot=a[0]; //设置基准值 i=0; j=n-1; while (i<j){ while (i<1 && ______) j--; //大于基准值者保持在原位置 if (i<j) { a[i] =a[j]; i++;} while(i<j&& ______) i++; //不大于基准值者保持在原位置 if (i<1) { a[j] =a[i]; 1--;} } a[i]=pivot; //基准元素归位 if (i>1 ) ______; //递归地对左孔序列进行快速排序 if (n-i-1>1 ) ______; //递归地对右孔序列进行快速排序 } int main() { int i, arr[] ={23,56,9,75,18,42,11,67}; quicksort(______); //调用quicksort对数组arr[]进行排序 for( i=0; i<sizeof(arr)/sizeof(int); i++ ) printf("%d\t",arr[i]); return 0; }
参考答案:
a[j]>pivot 或 a[j]>=pivot 或等价形式 a[i]<=pivot 或 a[i]<pivot 或等价形式 quicksort(a,i) 或 quicksort(a,j) 或等价形式 quicksort(a+i+1,n-i-1) 或 quicksort(a+j+1,n-j-1) 或等价形式 注:a+i+1可表示为&a[i+1],a+j+1可表示为&a[j+1] arrsizeof(arr)/sizeof(int) 注:sizeof(arr)/sizeof(int)可替换为8
解析:
本题考查的是对快速排序算法的理解和C语言的编程技能。根据题目描述和给出的代码片段,我们需要对代码中的空缺部分进行填补。
- 在第一个空处,我们需要找到一个条件来判断一个数是否大于基准值,因此应该填写“a[j]>pivot”或等价形式如“a[j]>=pivot”。这个条件用于在划分过程中将大于基准值的元素保持在原位置。
- 在第二个空处,我们需要找到一个条件来判断一个数是否小于或等于基准值,因此应该填写“a[i]<=pivot”或等价形式如“a[i]<pivot”。这个条件用于在划分过程中将小于或等于基准值的元素保持在原位置。
- 在第三个空处,我们需要递归地对左子序列进行快速排序。根据快速排序的递归特性,应该填写“quicksort(a,i)”或等价形式如“quicksort(&a[0],i)”,这里的参数表示对左子序列进行排序。这里的&a[0]和a是等价的,都表示数组的起始地址。
- 在第四个空处,我们需要递归地对右子序列进行快速排序。同样根据快速排序的递归特性,应该填写“quicksort(a+i+1,n-i-1)”,这里的参数表示右子序列的起始地址和长度。
- 在第五个空处,我们需要在main函数中调用quicksort函数对数组arr进行排序。根据函数的定义和参数传递方式,应该填写“arr,sizeof(arr)/sizeof(int)”或等价形式来表示数组arr和它的元素个数。注意这里可以使用sizeof运算符来计算数组的元素个数。
综上,我们已经根据题目要求对代码中的空缺部分进行了填补,完成了对快速排序算法的C语言实现。
4、
阅读以下说明和C代码,填补代码中的空缺,将解答填入答题纸的对应栏内。
[说明]
函数GetListElemPtr(LinkList L,int i)的功能是查找含头结点单链表的第i个元素。若找到,则返回指向该结点的指针,否则返回空指针。
函数DelListElem(LinkList L,int i,ElemType *e)的功能是删除含头结点单链表的第i个元素结点,若成功则返回SUCCESS,并由参数e带回被删除元素的值,否则返回ERROR。
例如,某含头结点单链表L如下图(a)所示,删除第3个元素结点后的单链表如下图(b)所示。
#define SUCCESS 0 #define ERROR -1 typedef int Status; typedef int ElemType;
链表的结点类型定义如下:
typedef struct Node{ ElemType data; struct Node *next; }Node,*LinkList; [C代码] LinkList GetListElemPtr(LinkList L,int i) { /*L是含头结点的单链表的头指针,在该单链表中查找第i个元素结点; 若找到,则返回该元素结点的指针,否则返回NULL */ LinkList p; int k; /*用于元素结点计数*/ if(i<1 || !L || !L->next) return NULL; k=1; p=L->next; /*令p指向第1个元素所在结点*/ while(p && ______){ /*查找第i个元素所在结点*/ ______; ++k; } return p; } Status DelListElem(LinkList L,int i,ElemType *e) { /*在含头结点的单链表L中,删除第i个元素,并由e带回其值*/ LinkList p,q; /*令P指向第i个元素的前驱结点*/ if(i==1) ______; else p=GetListElemPtr(L,i-1); if(!P || !p->next) return ERROR; /*不存在第i个元素*/ q=______; /*令q指向待删除的结点*/ p->next=q->next; //从链表中删除结点*/ ______; /*通过参数e带回被删除结点的数据*/ free(q); return SUCCESS; }
参考答案:
k<i p=p->next p=L p->next *e=q->data
解析:
本题考察的是对链表的基本操作以及指针的使用。
对于第一个函数GetListElemPtr,其目的是找到链表中第i个元素的指针。首先初始化指针p指向链表的第一个元素,然后使用一个循环来遍历链表,直到找到第i个元素或者到达链表尾部。在循环中,每次迭代都将指针p向后移动一个节点,同时计数器k自增。因此,第一个空应填写k<i,表示当k还没有达到i时继续循环查找。第二个空填写p=p->next,用于将p指向下一个节点。
对于第二个函数DelListElem,其目的是删除链表中的第i个元素。首先处理特殊情况,当i等于1时,直接让p指向头结点。否则,使用GetListElemPtr函数找到第i-1个元素的指针,然后让p指向第i个元素的前驱结点。接着,让q指向待删除的结点,即p的后一个结点。然后修改p的后继结点为q的后继结点,从而从链表中删除q节点。最后,通过参数e带回被删除结点的数据,并释放q节点所占用的内存。因此,第三个空填写p=L,第四个空填写p->next,第五个空填写*e=q->data。
5、阅读以下说明和C++代码,填补代码中的空缺,将解答填入答题纸的对应栏内。
[说明]
在股票交易中,股票代理根据客户发出的股票操作指示进行股票的买卖操作。其类图如下图所示,相应的C++代码附后。
类图
[C++代码] #include<iostream> #include<string> #include<vector> using namespace std; class Stock { private: string name; int quantity; public: Stock(string name,int quantity) {this->name=name; this->quantity =quantity;} void buy() {cout<<"[买进]股票名称:"<<name<<",数量:"<<quantity<< endl;} void sell() {cout<<"[卖出]股票名称:"<<name<<",数量:"<<quantity <<endl;} }; clasS order{ public: virtual void execute()=0; }; class BuyStock:______ { private: Stock* stock; public: BuyStock(Stock* stock){______ =stock; } void execute(){ stock一>buy(); } }; //类SellStock的实现与BuyStock类似,此处略 class Broker{ private: vector<Order*> orderList; public: void takeOrder(______ order)( orderLiSt.push back(order);} void placeorders() { for(int i=0;i<orderList.Size(); i++){______ ->execute();} 0rderLiSt.clear(); } }; class StockCommand{ public: VOid main(){ Stock* aStock=new Stock("股票A",10); Stock*bStock=new Stock("股票B",20); Order*buyStockOrder=new BuyStock(aStock); Order* sellStockOrder=new SellStock(bStock); Broker* broker=new Broker(); broker->takeOrder(buyStockorder); broker->takeOrder(sellStockOrder); broker-> ______ (); } }; int main(){ StockCommand* stockCommand=new StockCommand(); StockCommand->main(); delete StoCkCommand; }
参考答案:
publicOrder this->stock 或(*this).stock Order* orderList[i] 或 *(orderList+i) placeOrders
解析:
:
本题考查了C++面向对象程序设计和类的继承、对象指针操作等知识。根据题目描述和给出的代码片段,我们可以按照以下思路进行解析和填空:
(1) BuyStock类需要继承一个类,根据题目描述和代码中的Order虚类,我们需要继承Order类,因此填空为public Order。
(2) 在BuyStock类的构造函数中,我们需要初始化一个指向Stock对象的指针stock。在C++中,我们可以使用this指针来引用当前对象的成员变量。因此填空为this->stock或(*this).stock。
(3) 在Broker类的takeOrder函数中,我们需要接收一个Order类型的指针作为参数,因为BuyStock和SellStock都是Order的子类,所以可以接受它们的实例作为参数。因此填空为Order*。
(4) 在Broker类的placeorders函数中,我们需要遍历orderList中的每个元素并调用其execute函数。在C++中,我们可以使用数组索引或指针的方式来访问向量中的元素。因此填空为orderList[i]或*(orderList+i)。
(5) 在StockCommand类的main函数中,我们需要调用Broker类的placeorders函数来执行所有的订单。因此填空为placeOrders。
6、阅读以下说明和Java代码,填补代码中的空缺,将解答填入答题纸的对应栏内。
[说明]
在股票交易中,股票代理根据客户发出的股票操作指示进行股票的买卖操作。其类图如下图所示。相应的Java代码附后。
类图
[Java代码] import Java.util.ArrayList; import java.util.List; ClaSS Stock{ private String name; private int quantity; public Stock(String name,int quantity){ thiS.name=name;this.quantity=quantity; } public void buy(){ System.out.println("[买进]:"+name+",数量:" +quantity);} public void sell() {System.out.println("[卖出]:"+name+",数量:" +quantity);} } interface Order { VOid execute(); } class BuyStock ______ Order { private Stock Stock; public BuyStock(Stock stock){______=stock; } public void execute(){ stock.buy(); } } //类SellStock实现和BuyStock类似,略 clasS Broker{ private List<Order>orderList=new ArrayList<Order>(); Dublic void takeOrder(______ Order){ orderList.add(order); } public void placeorders(){ for {______ order:orderList) {order.execute(); } orderLiSt.clear(); } } public class StockCommand { public static void main(String[]args){ Stock aStock:new Stock("股票A",10); Stock bStock=new Stock("股票B",20); Order buyStockorder=new BuyStock(aStock); Order sellStockOrder=new SellSt0Ck(bStoCk); Broker broker=new Broker(); broker.takeOrder(buyStockorder); broker.takeOrder(sellStockOrder); broker.______; } }
参考答案:
implements this.stock Order Order placeOrders()
解析:
这道题目是关于Java语言程序设计的题目,涉及到类、对象、方法的定义和相关操作。我们需要根据给出的类图和Java代码,理解每个类和接口的作用,填补代码中的空缺。
首先,第一个空需要填写实现Order接口的关键字,即"implements"。在Java中,一个类可以实现一个或多个接口,这里BuyStock类需要实现Order接口。
其次,第二个空需要填写当前对象的stock属性,即"this.stock"。在BuyStock类的构造方法中,我们需要用当前对象的stock属性来接收传入的Stock对象。
然后,第三个空需要填写Order类型。因为BuyStock和SellStock都是Order的实现类,所以在创建这两个类的实例时,都需要使用Order类型作为类型。
接着,第四个空需要填写对orderList中每个对象的类型Order并能调用execute()的操作。在Broker类的placeOrders方法中,我们需要遍历orderList中的每个Order对象,并调用其execute方法。这里可以使用Java的foreach循环语法。
最后,第五个空需要调用placeOrders()方法。在StockCommand类的main方法中,我们需要创建Broker对象并调用其placeOrders方法来执行所有的股票交易指令。
喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!