boost库之multi_array

C++标准库提供了string、array、和vector,他们是一维数组,另有个组间valvarry可以实现多维的数值数组,但他不是容器,而且设计存在一些问题。多维数组虽然实际应用中没有一维数组那么普遍,但也是很有用的。在C++中除了原始数组,只能用vector<vector<T>>来代替了,虽然可用,但不太方便。
multi—array库解决了这个问题,它是一个多维容器,高效地实现了STL风格的多维数组,比使用原始多维数组或者vector of vector更好。

类摘要

multi_array很像标准容器,具有标准容器的大部分接口,它的类摘要如下:
template <typename Valuetype, std::size_t NumDims>
class multi_array
{
public:
    /// 内部类型定义
    template <std::size_t Dims> struct subarray;
    template <std::size_t Dims> struct const_subarray;
    template <std::size_t Dims> struct array_view;
    template <std::size_t Dims> struct const_array_view;

    multi_array();
    explicit multi_array(const ExtentList& size, const storage_order_type& store = c_storage_order());
    explicit multi_array(const extents_tuple& ranges, const storage_order_type& store = c_storage_order());

    iterator   begin();///迭代器
    iterator   end();
    size_type  size()const;
    size_type  num_elements()const;
    size_type  num_dimensions()const;

    reference  operator[](index i);/// 重载operator[]
    element&   operator()(const IndexList& indices);
    array_view<Dims>::type  operator[](const indices_tuple& r);
    const_array_view<Dims>::type operator[](const indices_tuple& r)const;

    element*       data();///维度操作
    element*       origin();
    const element*  origin()const;
    const size_type* shape()const;
    const index*     strides()const;
    const index*     index_bases()const;
    const storage_order_tpye& storage_order()const;

    bool operator==(const multi_array& rhs);

    void       reshape(const SizeList& sizes);
    void       assign(InputIterator begin, InputIterator end);
    void       reindex(const BaseList& values);
    void       reindex(index value);
    multi_array& resize(const extentList& extents);
    multi_array& resize(extents_tuple& extents);
};
multi_array 是递归定义的,它的每个维度都是一个multi_array,最底层的则是一个一维的multi—array,因此multi-array是组个模式的一个具体应用

用法

multi_array<int, 3> ma;
定义了一个三维数组ma,相当于int ma[x][y][z].
但仅仅指定了维数还是不够,多维数组还需要指定维度的具体值。
multi—array为了完成这个任务特意提供了extent—gen类和预定义的一个实例boost::extents,它重载了operator[],用起来就像一个原始多维数组,例如:
multi_array<int, 3> ma(extents[2][3][4]);
多维数组的总维度可以用成员函数num_dimensions()获得,它的返回值就是模板参数中的NumDims. 函数shape()返回一个常量指针(数组),里面有NumDims个元素,表明了具体各个维度的值。
  /// 申明一个3维数组
    multi_array<int, 3> ma(extents[2][3][4]);

    auto shape = ma.shape();
    for (size_t i = 0; i < ma.num_dimensions(); ++i)
    {
        cout << shape[i] << ",";
    }
    cout << endl << ma.num_elements() << endl;
    /// 可以像普通数组一样遍历
    for (int i = 0,  v = 0; i < 2; ++i)
        for (int j = 0; j < 3;++j)
            for (int k = 0;k < 4;++k)
            {
                ma[i][j][k] = v++;
            }
    /// 输出多维数组内所有元素
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 3;++j)
        {
            for (int k = 0;k < 4;++k)
            {
                cout << ma[i][j][k] << ",";
            }
            cout << endl;
        }
        cout << endl;
    }
    //cout << ma[2][3][4];
    std::array<size_t, 3> idx = {0,1,2};/// 使用array
    ma(idx) = 10; /// 使用operator()
    cout << ma(idx) << endl;

改变形状和大小

multi—array可以在运行时使用成员函数reshape()改变多维数组的形状,即变动各维度的大小,但总维度和元素数量保持不变,变动前的维度乘积与变动后的维度乘积必须相等
    multi_array<int, 3> ma(extents[2][3][4]);
    assert(ma.shape()[0] == 2);

    std::array<std::size_t, 3> arr = {4,3,2};
    ma.reshape(arr); /// [2][3][4]->[4][3][2]
    assert(ma.shape()[0] == 4);

    ma.resize(extents[2][9][9]);
    assert(ma.num_elements() == 2*9*9);
    assert(ma.shape()[1] == 9);

创建子视图

多维数组的操作是比较复杂的,multi_array库允许用户为多维数组创建一个只查看其中一部分数据的子视图(view),子视图即可以与原始数组拥有相同的维数,也可以少于原来的维数。
    typedef multi_array<int, 2> ma_type;
    multi_array<int, 2> ma(extents[3][4]) ;

    typedef ma_type::index_range range;
    //indices[range(0,2)][range(0,2)];
    ///需要用index_gen类的预定义的实例indices来
    ///定义子视图的索引
    auto view = ma[indices[range(0,2)][range(0,2)] ];

    cout << view.num_elements() << endl;
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 2;++j)
        {
            cout << view[i][j] << ",";
        }
        cout << endl;
    }
    cout << *view.shape() << endl;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值