两道相似的重要的多维数组模板题比较

两道模板题,同样与多维数组有关,需要自己实现中括号。以及各种赋值操作。

CArray3d三维数组模板类

实现一个三维数组模版CArray3D,可以用来生成元素为任意类型变量的三维数组,输出指定结果

#include <iostream>
#include <iomanip> 
#include <cstring>
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

解法

内部类,多个中括号返回的类型不同。需要重载对象到指针的强制类型转换。

 1 template <class T>
 2 class CArray3D
 3 {
 4 public:
 5     int layer1, layer2, layer3;
 6     class CArray2D {
 7     public:
 8         int layer1, layer2;
 9         T* inner;
10         CArray2D():layer1(1),layer2(1){
11             inner = new T[1];
12         }
13         void settings(int a, int b) {
14             layer1 = a;
15             layer2 = b;
16             delete[]inner;
17             inner = new T[a*b + 1];
18         }
19         T* operator[](int b) {
20             return inner +layer2 * b;
21         }
22         operator T*() {
23             return inner;
24         }
25     };
26     CArray2D*p;
27     CArray3D(int a,int b,int c):layer1(a),layer2(b),layer3(c){
28         p = new CArray2D[a + 1];
29         for (int j = 0; j < a; ++j)
30             p[j].settings(b, c);
31     }
32     CArray2D& operator[](int a) {
33         return p[a];
34     }
35 
36 };

变式

加入了memset以后,就不能直接用上面的解法。因为layer作为变量占据空间。

#include <iostream>
#include <iomanip>
#include <cstring>
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 )
        for( int j = 0; j < 4; ++j )
            for( int k = 0; k < 5; ++k )
                a[i][j][k] = No ++;
    PrintA();
    memset(a, -1, 60 * sizeof(int));        //注意这里
    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;
}

需要转换思路,将外围的指针变成T类型,将中括号进行类型转换。

template <class T>
class CArray3D
{
public:
    class CArray2D {
    public:
        int layer2;
        T* inner;
        CArray2D(T*p,int c) :inner(p), layer2(c) {}
        T* operator[](int b) {
            return inner + layer2 * b;
        }
        operator T*() {
            return inner;
        }
    };
    T*p;
    int layer1, layer2, layer3;
    CArray3D(int a, int b, int c) :layer1(a), layer2(b), layer3(c) {
        p = new T[a*b*c];
    }
    CArray2D operator[](int a) {
        return CArray2D(p + a * layer2*layer3, layer3);
    }
    operator void*() {
        return (void*)p;
    }
};

 

积分图

对于一幅灰度的图像,积分图中的任意一点(x,y)的值是指从图像的左上角到这个点的所构成的矩形区域内所有的点的灰度值之和。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class IntegralImage{
// 在此处补充你的代码
};
int main(){
    int H, W;
    cin >> H >> W;
    int ** image = new int*[H];
    for(int i=0;i<H;++i){
        image[i]=new int[W];
    }
    for(int i=0;i<H;++i)
    for(int j=0;j<W;++j)
        cin >> image[i][j];
    IntegralImage it(H,W);
    for_each(image, image+H, it);
    for(int i=0;i<H;++i){
        for(int j=0;j<W;++j)
            cout<<it[i][j]<<" ";
        cout<<endl;
    }
   
}

输入

第一行两个整数,分别是图像的宽、高H, W
接下来H*W的矩阵,分别代表图像的每个像素值

输出

积分图中每个点的值, H*W的矩阵,每个像素之间用空格分开

样例输入

2 3
1 2 3
1 0 0

样例输出

1 3 6
2 4 7

解法

这个题的关键在于赋值操作,是用for each,参数类型为一维的指针。中括号只有两层,所以不用像上一题一样写内部类。

 1 class IntegralImage{
 2 public:
 3     int H, W;
 4     int **p;
 5     int counts = 0;
 6     IntegralImage(int a, int b) :H(a), W(b) {
 7         p = new int*[H];
 8         for (int i = 0; i < H; i++)
 9             p[i] = new int[W];
10     }
11     int* operator[](int k) {
12         return p[k];
13     }
14     void operator()(int *image) {
15         for (int j = 0; j < W; j++) {
16             if (counts == 0) {
17                 if (j == 0)
18                     p[counts][j] = image[j];
19                 else
20                     p[counts][j] = p[counts][j - 1] + image[j];
21             }
22             else {
23                 if (j == 0)
24                     p[counts][j] = p[counts - 1][j] + image[j];
25                 else {
26                     p[counts][j] = p[counts][j - 1] + p[counts - 1][j] - p[counts - 1][j - 1] + image[j];
27                 }
28             }
29         }
30         counts++;
31     }
32 };

 

posted @ 2021-07-17 14:43  永远是个小孩子  阅读(92)  评论(0编辑  收藏  举报