5

我想创建一个双精度向量的向量,并希望它已经具有 (32,32,16) 个元素,而无需手动将所有这些推回。有没有办法在初始化期间做到这一点?(我不在乎推动什么价值)。

我想要一个 3 维数组,第一个维度有 32 个,第二个维度有 32 个,第三个维度有 16 个元素。

4

4 回答 4

8

一个班轮:

std::vector< std::vector< std::vector<double> > > values(32, std::vector< std::vector<double> >(32, std::vector<double>(16, 0.0)));

或打破界限:

typedef std::vector<double> v_type;
typedef std::vector<v_type> vv_type;
typedef std::vector<vv_type> vvv_type;

vvv_type values(32, vv_type(32, v_type(16, 0.0)));

我会说这分配了很多对象(32 * 32 * 16)。

单个向量会起作用吗?

std::vector<double> values(32*32*16, 0.0)

那将是 32*32*16-1 少new

于 2010-06-08T15:24:24.827 回答
3

向量的一个 ctor 允许您指定要复制到向量元素中的大小和值。我不太确定“(32,32,16)”元素是什么意思,但是您可以执行以下操作:

// create a vector containing 16 elements set to 2
std::vector<int> temp(16, 2);   

// create a vector of 32 vectors, each with 16 elements set to 2
std::vector<std::vector<int> > values(32, temp);
于 2010-06-08T15:17:39.600 回答
2

干得好:

vector<vector<vector<int> > > k(32, vector<vector<int> >(32, vector<int>(16,0)));

我什至不会问为什么你会想要这样一个怪物,而不是仅仅使用一个vector带有你自己的索引方案的单个。

于 2010-06-08T15:22:55.190 回答
0

由于事先知道大小,并且您需要将整个数组转换为一维数组(对于 OpenGL),为什么不为它创建一个类呢?我创建了一个基于模板的 3D 数组实现,希望对您有用。

用法:

typedef Array3D<double, 3, 3, 3> DoubleArray333;
DoubleArray333 array;
Double val = 0.0;
for (size_t i = 0; i < DoubleArray333::SizeX; ++i)
{
 for (size_t j = 0; j < DoubleArray333::SizeY; ++j)
 {
  for (size_t k = 0; k < DoubleArray333::SizeZ; ++k)
  {
   array(i, j, k) = val++;
  }
 }
}
for (size_t i = 0; i < DoubleArray333::ArraySize; ++i)
{
 std::cout<<array[i]<<" ";
}


Array3D 头文件:

#pragma once

#include <exception>
#include <sstream>
#include <utility>
#include <memory>

/**
 * \brief   A 3D array of variable type and size.
 * \author  Vite Falcon
 * \date    08/06/2010
**/
template <typename T, int x, int y, int z>
class Array3D
{
private:
    T* m_array;

    /**
     * \brief   Validate the index range of different dimensions.
     * \remarks Vite Falcon, 08/06/2010.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \exception   std::out_of_range   Thrown when one of the indices is out-of-range.
     * \param   x   The width index.
     * \param   y   The height index.
     * \param   z   The depth index.
    **/
    inline void validateRange(size_t x, size_t y, size_t z)
    {
        if (x >= SizeX || y >= SizeY || z >= SizeZ)
        {
            std::stringstream ss;
            ss<<"Index out of range when accessing ("<<x<<", "<<y<<", "<<z<<
                ") when total size is ("<<SizeX<<", "<<SizeY<<", "<<SizeZ<<").";
            throw std::out_of_range(ss.str());
        }
    }

    /**
     * \brief   Validates the given array index.
     * \remarks Vite Falcon, 08/06/2010.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \exception   std::out_of_range   Thrown when the index is out-of-range.
     * \param   index   Zero-based index of the array.
    **/
    inline void validateIndex(size_t index)
    {
        if (index >= ArraySize)
        {
            std::stringstream ss;
            ss<<"Index out of range when accessing array by index "<<index<<
                " when total array size is "<<ArraySize<<".";
            throw std::out_of_range(ss.str());
        }
    }
public:
    static const size_t SizeX;
    static const size_t SizeY;
    static const size_t SizeZ;
    static const size_t ArraySize;

    typedef Array3D<T,x,y,z> MyType;

    /**
     * \brief   Default constructor. 
     * \author  Vite Falcon
     * \date    08/06/2010
    **/
    Array3D(void)
        :m_array(new T[ArraySize])
    {
    }

    /**
     * \brief   Copy constructor.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   other   The other.
    **/
    Array3D(const MyType& other)
        :m_array(new T[ArraySize])
    {
        memcpy_s(m_array, sizeof(T)*ArraySize, other.m_array, sizeof(T)*ArraySize);
    }

    /**
     * \brief   Destructor.
     * \author  Vite Falcon
     * \date    08/06/2010
    **/
    ~Array3D(void)
    {
        delete[] m_array;
        m_array = 0;
    }

    /**
     * \brief   Gets the value at a particular array index.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   array_index Zero-based index of the array.
     * \return  The value at the given index.
    **/
    inline T& at(size_t array_index)
    {
        return (*this)[array_index];
    }

    /**
     * \brief   Gets the value at a particular array index (const version)
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   array_index Zero-based index of the array.
     * \return  The value at the given index.
    **/
    inline const T& at(size_t array_index) const
    {
        return (*this)[array_index];
    }

    /**
     * \brief   Gets the value in the array from the given 3D indices.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   x   The width index.
     * \param   y   The height index.
     * \param   z   The depth index.
     * \return  The value at the given indices.
    **/
    inline T& at(size_t x, size_t y, size_t z)
    {
        return (*this)(x, y, z);
    }

    /**
    * \brief    Gets the value in the array from the given 3D indices (const version).
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   x   The width index.
     * \param   y   The height index.
     * \param   z   The depth index.
     * \return  The value at the given indices.
    **/
    inline const T& at(size_t x, size_t y, size_t z) const
    {
        return (*this)(x, y, z);
    }

    /**
     * \brief   The '()' operator to access the values as a 3D array.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \return  The value at the given indices.
     *
     * \param   x   The width index.
     * \param   y   The height index.
     * \param   z   The depth index.
    **/
    inline T& operator ()(size_t x, size_t y, size_t z)
    {
        validateRange(x, y, z);
        return m_array[x*SizeY*SizeZ + y*SizeZ + z];
    }

    /**
     * \brief   The '()' operator to access the values as a 3D array (const version).
     * \author  Vite Falcon
     * \date    08/06/2010
     * \return  The value at the given indices.
     *
     * \param   x   The width index.
     * \param   y   The height index.
     * \param   z   The depth index.
    **/
    inline const T& operator()(size_t x, size_t y, size_t z) const
    {
        validateRange(x, y, z);
        return m_array[x*SizeY*SizeZ + y*SizeZ + z];
    }

    /**
     * \brief   The '[]' operator to access the values as a 1D array.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   array_index Zero-based index of the array.
     * \return  Value at the given index.
    **/
    inline T& operator[](size_t array_index)
    {
        validateIndex(array_index);
        return m_array[array_index];
    }

    /**
     * \brief   The '[]' operator to access the values as a 1D array.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   array_index Zero-based index of the array.
     * \return  Value at the given index.
    **/
    inline const T& operator[](size_t array_index) const
    {
        validateIndex(array_index);
        return m_array[array_index];
    }

    /**
     * \brief   Fills the array with the given value.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   val The value to fill the array.
    **/
    void fill(const T& val)
    {
        for (size_t i = 0; i < ArraySize; ++i)
        {
            m_array[i] = val;
        }
    }

    /**
     * \brief   Gets the raw array.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \return  The 1D array.
    **/
    T* getArray()
    {
        return m_array;
    }

    /**
     * \brief   Swaps the current array with the given one.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param [in,out]  other   The other.
    **/
    void swap(MyType& other)
    {
        std::swap(m_array, other.m_array);
    }

    /**
     * \brief   Copy operator.
     * \author  Vite Falcon
     * \date    08/06/2010
     * \param   other   The other.
     * \return  A shallow copy of this object.
    **/
    MyType& operator = (const MyType& other)
    {
        MyType temp(other);
        swap(temp);
        return *this;
    }
};

template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeX = x;

template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeY = y;

template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeZ = z;

template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::ArraySize = x*y*z;


您还可以使用以下函数将指向数组的指针作为一维数组:
double* double_array = array.getArray();

编辑:更改用法以使用 double 而不是 int 显示它。

于 2010-06-08T21:07:42.147 回答