北大程序设计与算法(三)测验题汇总(2020春季)
实现一个三维数组模版CArray3D,可以用来生成元素为任意类型变量的三维数组,输出指定结果
#include
#include
#include
using namespace std;
template <class T>
class CArray3D
{
// 在此处补充你的代码
};
CArray3D<int> a(3,4,5);
CArray3D<double> b(3,2,2);
void PrintA()
{
for(int i = 0;i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for(int j = 0; j < 4; ++j) {
for(int k = 0; k < 5; ++k)
cout << a[i][j][k] << "," ;
cout << endl;
}
}
}
void PrintB()
{
for(int i = 0;i < 3; ++i) {
cout << "layer " << i << ":" << endl;
for(int j = 0; j < 2; ++j) {
for(int k = 0; k < 2; ++k)
cout << b[i][j][k] << "," ;
cout << endl;
}
}
}
int main()
{
int No = 0;
for( int i = 0; i < 3; ++ i ) {
a[i];
for( int j = 0; j < 4; ++j ) {
a[j][i];
for( int k = 0; k < 5; ++k )
a[i][j][k] = No ++;
a[j][i][i];
}
}
PrintA();
memset(a[1],-1 ,20*sizeof(int));
memset(a[1],-1 ,20*sizeof(int));
PrintA();
memset(a[1][1],0 ,5*sizeof(int));
PrintA();
for( int i = 0; i < 3; ++ i )
for( int j = 0; j < 2; ++j )
for( int k = 0; k < 2; ++k )
b[i][j][k] = 10.0/(i+j+k+1);
PrintB();
int n = a[0][1][2];
double f = b[0][1][1];
cout << "****" << endl;
cout << n << "," << f << endl;
return 0;
}
输入
无
输出
等同于样例
样例输入
无
样例输出
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
20,21,22,23,24,
25,26,27,28,29,
30,31,32,33,34,
35,36,37,38,39,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
0,1,2,3,4,
5,6,7,8,9,
10,11,12,13,14,
15,16,17,18,19,
layer 1:
-1,-1,-1,-1,-1,
0,0,0,0,0,
-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,
layer 2:
40,41,42,43,44,
45,46,47,48,49,
50,51,52,53,54,
55,56,57,58,59,
layer 0:
10,5,
5,3.33333,
layer 1:
5,3.33333,
3.33333,2.5,
layer 2:
3.33333,2.5,
2.5,2,
7,3.33333
提示
建议做法:
这道题,我也是根据提示做出来的,不然没有思路,因为只会二维的写法。a[i][j][k] 这个表达式的第一个[]返回一个内部类的对象,该内部类也重载了[],且返回值为指针。这句话诠释了我们该怎么做:
class CArray3D
{
public:
T* p;
int f, r, c; //数组共f层,每层r行,每行c列
CArray3D(int _f, int _r, int _c) :f(_f), r(_r), c(_c) {
p = new T[f * r * c];
}
~CArray3D() { delete[] p; }
};
class CArray2D {
public:
T* fp; // fp是一层的元素的起始地址
int c; //数组每行c列
T* operator[](int r) {
return fp + r * c; //返回本层的第 r行起始地址
}
CArray2D(T* p_, int c_) :fp(p_), c(c_) { }
};
CArray2D operator[](int _f) {//第_f层元素的起始地址
return CArray2D(p + _f * r * c, c);
}
那么这样就可以了,关键部分完成了,但是仅仅以上代码还是不行的,因为比如在以下地方:
memset(a[1],-1 ,20*sizeof(int));
memset(a[1],-1 ,20*sizeof(int));
我们知道此时的a[1]
是一个对象,是不能直接用于初始化的,那么,只有通过类型转换函数了:
operator T* () {
return fp; //返回值本层的起始地址
}
将一个对象转换成T*
类型即可顺利通过了。
完整的就是:
class CArray3D
{
public:
T* p;
int f, r, c; //数组共f层,每层r行,每行c列
class CArray2D {
public:
T* fp; // fp是一层的元素的起始地址
int c; //数组每行c列
CArray2D(T* p_, int c_) :fp(p_), c(c_) { }
T* operator[](int r) {
return fp + r * c; //返回本层的第 r行起始地址
}
operator T* () {
return fp; //返回值本层的起始地址
}
};
CArray3D(int _f, int _r, int _c) :f(_f), r(_r), c(_c) {
p = new T[f * r * c];
}
CArray2D operator[](int _f) {//第_f层元素的起始地址
return CArray2D(p + _f * r * c, c);
}
~CArray3D() { delete[] p; }
};