}
}
二、编程题
定义一个求两个集合交集的类DataSet,并在主函数中用两个字符串进行测试。
具体要求如下:
(1)私有数据成员:
charp1,p2;指向存放两个原始集合的存储空间的指针
char*p;指向存放上述两个集合的交集的存储空间的指针
(2)公有成员函数
DataSet(chara[],charb[]);初始化两个原始集合,同时为指针p动态分配内存空间,大小为数组a和b中较大的尺寸
voidcompress(char*p);消除指针p所指向的数组中的重复元素
voidsetcompress();通过分别调用compress函数,消除p1和p2所指向数据中的重复元素。
由于集合没有重复的元素,因此在创建DataSet对象后,必须调用setcompress函数
voidintersection();求指针p1和p2所指向集合的交集,结果存放在指针p所指向的存储空间中
voidprint();输出两个原始集合及它们的交集
~DataSet();实现必要的功能
(3)在主函数中,创建一个DataSet类型的对象,在消除该对象中每个原始集合的重复元素之后,求它们的交集,并输出。
VC02
一、改错题
下列程序的功能是:
查询一个带通配符”?
”的字符串sub在另一个字符串str中出现的次数,其中通配符”?
”可以代替任何一个字符。
例如,字符串”a?
c”在”abcdabceascac”中出现了3次(下划线部分),”a?
a”在”abacadca”中出现了2次,”a?
”在”abaca”出现了2次。
含错误的源程序如下:
#include
voidfun(char*str,char*sub)
{
intn=0;
while(*str)
{
char*p1=str,*p2=sub;
while(*p1==*p2&&*p2=='?
')
{
if(*(p2+1)=='\0'&&*p1)
{
n++;
continue;
}
p1++;p2++;
}
str++;
}
returnn;
}
voidmain()
{
charstr[80],sub[10];
cout<<"请输入被查询的字符:
\n";
cin.getline(str,79);
cout<<"请输入要查询的字符:
\n";
cin.getline(sub,9);
intk=fun(&str,&sub);
if(k)
cout<<"出现了"<\n";
else
cout<<"没有出现\n";
}
正确的源程序如下:
#include
intfun(char*str,char*sub)
{
intn=0;
while(*str)
{
char*p1=str,*p2=sub;
while(*p1==*p2||*p2=='?
')
{
if(*(p2+1)=='\0'&&*p1)
{
n++;
break;
}
p1++;p2++;
}
str++;
}
returnn;
}
voidmain()
{
charstr[80],sub[10];
cout<<"请输入被查询的字符:
\n";
cin.getline(str,80);
cout<<"请输入要查询的字符:
\n";
cin.getline(sub,10);
intk=fun(str,sub);
if(k)
cout<<"出现了"<\n";
else
cout<<"没有出现\n";
}
二、编程题
编程实现对大于1的整数进行质因数分解。
所谓整数的质因数分解是指将整数分解为其所有质数(素数)因数的积,例如,60=2*2*3*5。
定义一个类Decompose实现上述功能。
具体要求如下:
(1)私有数据成员
int*a;指向存放质因数的动态存储空间
intnum;待分解质因数的整数
intn;质因数的个数
(2)公有成员函数
Decompose(intm);用m初始化num,并将n初始化为0,a初始化为空指针
voidprint();输出整数num的质因数
voidprimenum();求整数num的所有质因数(保留重复部分,例如60的质因数为2,2,3,5),并将这些质因数存放到指针a所指向的存储空间中
~Decompose();释放动态分配的存储空间
(3)在主函数中完成对该类的测试。
从键盘输入一个大于1的整数number,定义类Decomose的对象d,并用number初始化d,调用函数primenum()求number的所有质因数,最后输出number的质因数分解结果。
VC03
一、改错题
折半查找的基本思想为:
假设一数据集是按升序排列的,如果要查找的数小于该数据集第一个元素或大于该数据集的最后一个元素,则查找失败;否则,计算数据集的中间元素(如果元素个数为偶数2n,则中间元素约定为第n个元素),如果中间元素正好等于要查找的数,则查找成功;如果中间元素小于要查找的数,则从中间元素往后查找,否则从中间元素往前查找;在缩小了的范围内重复应用上述方法既可。
下列程序中的函数search用递归方法实现在数组a中查找key的功能,如果查找成功,返回数组a中相应元素的下标值,否则返回-1,其中n1和n2分别为当前查找的数组下标范围。
主函数首先随机生成15个整数,然后用折半查找法在其中查找某一个键盘输入的数,并输出查找结果。
含错误的源程序如下:
#include
#include
intsearch(inta[],intkey,intn1,intn2)
{
if(a[n1]>key&&a[n2]return-1;
if(key==a[n2])
returnn2;
if(key==a[n1])
returnn1;
intn=(n2-n1)/2;
if(n==n1||n==n2)
returnn;
if(a[n]==key)
returnn;
if(a[n]returnsearch(a,key,n1,n);
else
returnsearch(a,key,n,n2);
}
voidsort(int*p,intn)//对数组排序
{
for(inti=0;ifor(intj=i+1;jif(*(p+i)>*(p+j))
{
intt=*(p+i);*(p+i)=*(p+j);*(p+j)=t;
}
}
voidmain()
{
intdata[15],k,index;
for(inti=0;i<15;i++)
data[i]=rand()%100;//系统函数rand的功能是产生一个随机整数
sort(data,15);
for(i=0;i<15;i++)
cout<cout<<'\n';
cout<<"inputakeytosearch:
";
cin>>k;
index=search(data,k,0,14);
if(index==-1)
cout<<"Thenumber"<\n";
else
{
cout<<"index="<cout<<"data["<}
}
正确的源程序如下:
#include
#include
intsearch(inta[],intkey,intn1,intn2)
{
if(a[n1]>key||a[n2]return-1;
if(key==a[n2])
returnn2;
if(key==a[n1])
returnn1;
intn=(n2+n1)/2;
if(n==n1&&n==n2)
returnn;
if(a[n]==key)
returnn;
if(a[n]returnsearch(a,key,n+1,n2);
else
returnsearch(a,key,n1,n-1);
}
voidsort(int*p,intn)//对数组排序
{
for(inti=0;ifor(intj=i+1;jif(*(p+i)>*(p+j))
{
intt=*(p+i);*(p+i)=*(p+j);*(p+j)=t;
}
}
voidmain()
{
intdata[15],k,index;
for(inti=0;i<15;i++)
data[i]=rand()%100;//系统函数rand的功能是产生一个随机整数
sort(data,15);
for(i=0;i<15;i++)
cout<cout<<'\n';
cout<<"inputakeytosearch:
";
cin>>k;
index=search(data,k,0,14);
if(index==-1)
cout<<"Thenumber"<\n";
else
{
cout<<"index="<cout<<"data["<}
}
二、编程题
定义一个类Array,求一个二维数组所有元素的平均值(精确到小数点后3位数),并将该平均值的整数和小数部分分别逆序后输出(如平均值为342.083,则将其整数和小数部分分别逆序后变为243.380)。
类Array的具体要求如下:
(1)私有数据成员
inta[3][4];
floatave1,ave2;ave1,ave2分别存放数组a中所有元素的平均值及其逆序值
(2)公有成员函数
Array(intt[][4],intn);对私有成员a初始化
voidaverage();计算ave1的值
voidinvert();按题目要求对ave1进行逆序处理,得到ave2
voidprint();输出所有成员数据
(3)在主函数中对该类进行测试。
使用如下二维数组作为测试数据:
112211630200
524362651322
2696071054
代码如下:
#include
#include
classArray{
private:
inta[3][4];
floatave1,ave2;
public:
Array(intt[][4],intn)
{
for(inti=0;ifor(intj=0;j<4;j++)
a[i][j]=t[i][j];
}
voidaverage()
{
floats=0;
for(inti=0;i<3;i++)
for(intj=0;j<4;j++)
s+=a[i][j];
ave1=s/(3*4);
ave1=int(ave1*1000+0.5)/1000.0;
}
voidinvert()
{
inta1=ave1,s1=0;
while(a1>0)
{
s1=s1*10+a1%10;
a1=a1/10;
}
inta2,s2=0,n=0;
a2=int(ave1*1000+0.5)%1000;
while(++n<=3)
{
s2=s2*10+a2%10;
a2=a2/10;
}
ave2=s1+s2/1000.0;
}
voidprint()
{
for(inti=0;i<3;i++)
{
for(intj=0;j<4;j++)
cout<cout<}
cout<<"ave1="<cout.setf(ios:
:
fixed);
cout<<"ave2="<}
};
voidmain()
{
intt[3][4]={112,211,630,200,524,362,651,322,269,60,710,54};
Arrays(t,3);
s.average();
s.invert();
s.print();
}
VC04
一、改错题
一个二维数组的每行元素的逆序变换是指将该二维数组每行元素的次序颠倒。
例如,二维数组{{1,2,3,4},{5,6,7,8},{9,10,11,12}},经过每行元素逆序变换后的数组为{{4,3,2,1},{8,7,6,5},{12,11,10,9}}。
下列程序实现了二维数组每行元素的逆序变换。
在该程序中,将二维数组首行地址传递给函数inverse的参数p,其中参数n为所传递的二维数组的列数。
函数print可以打印二维数组,其中二维数组以一维数组的形式传递给指针p,m和n分别表示二维数组的行数和列数。
含错误的源程序如下:
#include
voidinverse(int*p,intn)
{
int*p1=p,*p2=p1+n;
while(p1{
intt=*p1;
*p1=*p2;
*p2=t;
p1++;p2--;
}
}
voidprint(int*p,intm,intn)
{
int*p1=p,*p2=p1+m*n-1;
while(p1<=p2)
{
intcount;
while(count++cout<<*p1++<<'\t';
cout<}
}
voidmain()
{
inta[3][4];
for(inti=0;i<3;i++)
for(intj=0;j<4;j++)
a[i][j]=i*4+j+1;
for(i=0;i<3;i++)
inverse(a,4);
print(a,3,4);
}
正确的源程序如下:
#include
voidinverse(int(*p)[4],intn)
{
int*p1=*p,*p2=p1+n-1;
while(p1{
intt=*p1;
*p1=*p2;
*p2=t;
p1++;p2--;
}
}
voidprint(int*p,intm,intn)
{
int*p1=p,*p2=p1+m*n-1;
while(p1<=p2)
{
intcount=0;
while(count++cout<<*p1++<<'\t';
cout<}
}
voidmain()
{
inta[3][4];
for(inti=0;i<3;i++)
for(intj=0;j<4;j++)
a[i][j]=i*4+j+1;
for(i=0;i<3;i++)
inverse(a+i,4);
print(*a,3,4);
}
二、编程题
编写一个程序求直角坐标系中点到直线的距离。
具体要求如下:
(1)定义一个点的类Point,含有:
私有数据成员:
floatx,y;分别代表点的横坐标和纵坐标
公有成员函数:
Point(floata,floatb);分别对x和y初始化
floatgetX(),floatgetY();分别返回横坐标和纵坐标
voidprint();以(x,y)的形式输出点
(2)定义一个直线类Line,含有:
私有数据成员:
Pointp1,p2;分别表示直线的两个端点
公有成员函数:
Line(Point&,Point&);分别对p1和p2初始化
友元函数floatdistance(Line&p,Point&q);计算并输出点到直线的距离
点(x,y)到由(x1,y1)和(x2,y2)两点确定的直线的距离公式为:
(3)在主函数中利用上述类定义一个点和一条直线,计算并输出点到直线间的距离。
VC05
一、改错题
用二分法解方程f(x)=0的具体算法如下:
(1)输入x1、x2,直至f(x1)与f(x2)异号,说明方程在x1、x2之间有解
(2)求x1和x2的中点x0
(3)如果f(x0)与f(x1)同号,表明方程的解在x0与x2之间,用x0取代x1;否则方程的解在x0与x1之间,用x0取代x2
(4)如果f(x0)的值足够小,则方程的近似解为x0;否则重复执行步骤
(2)、(3)、(4),直至f(x0)足够小
(5)输出方程的解x0
要求用二分法解方程x2+4x-4=0和x3+2x2+3x-15=0。
含错误的源程序如下:
#include
#include
doublef1(doublex)
{returnx*x+4*x-4;}
doublef2(doublex)
{returnx*x*x+2*x*x+3*x-15;}
voidxx(double(*fp)(double),double&a,double&b)
{
do
{
cout<<"请输入方程解的区间:
";
cin>>a>>b;
}while(fp(a)*fp(b)<0);
}
voidfun(double(*fp)(double))
{
doublex0,x1,x2;
xx(fp,&x1,&x2);
do
{
x0=(x2-x1)/2;
cout<if(fp(x0)*fp(x1)>0)
x2=x0;
else
x1=x0;
}while(fabs(fp(x0))>1e-5);
cout<<"方程的解为:
"<}
voidmain()
{
cout<<"解第一个方程:
\n";
fun(f1);
cout<<"解第二个方程:
\n";
fun(f2);
}
正确的源程序如下:
#include
#include
doublef1(doublex)
{returnx*x+4*x-4;}
doublef2(doublex)
{returnx*x*x+2*x*x+3*x-15;}
voidxx(double(*fp)(double),double&a,double&b)
{
do
{
cout<<"请输入方程解的区间:
";
cin>>a>>b;
}while(fp(a)*fp(b)>=0);
}
voidfun(double(*fp)(double))
{
doublex0,x1,x2;
xx(fp,x1,x2);
do