【问题标题】:Dynamic Safe 2D Jagged Array in C++C++ 中的动态安全二维交错数组
【发布时间】:2019-03-25 07:33:57
【问题描述】:

我应该如何将 Dynamic Safe 2D 数组类修改为 Dynamic Safe 2D 锯齿状数组类?我读过一篇文章,最好也更安全地使用动态安全或动态安全二维数组,以避免初始化大小小于 0 的数组或大小大于其原始大小的数组。大多数时候,我们会遇到过度递归的问题,比如使用回溯来寻找迷宫的路径。所以我试图实现动态安全的二维锯齿数组类,但我不明白我应该如何实现它?

//Dynamic Safe 2D array class 
template <class T> 

class DS2DA 
{ 
  private: 
    T **Data; 
    int nRow; 
    int nCol; 

public: 

DS2DA () 
{ 
    nRow=0; 
    nCol=0;
    Data=nullptr; 
} 

DS2DA (int nRow,int nCol) 
{ 
    this->nRow=nRow; 
    this->nCol=nCol; 
    Data=new T * [nRow]; 

    for (int i=0;i<nRow;i++) 
    { 
        Data[i]=new T [nCol];
    }

    for (int i=0;i<nRow;i++) 
    { 
        for (int j=0;j<nCol;j++) 
        { 
            Data[i][j]=0; 
        }
    }
} 

T & operator () (int n1,int n2)   
{ 
    if ((n1<0 or n1>this->nRow) or (n2<0 or n2>this->nCol)) 
    { 
        cout<<"Array out of bound";
        exit (1); 
    } 

    else 
        return (Data[n1][n2]); 
 } 

};

//Driver Program 

int main () 
{
  DS2DA <double> obj1 (3,3); 
  int input; 

  for (int i=0;i<3;i++) 
  { 
    cout<<"Row "<<i+1<<endl; 

    for (int j=0;j<3;j++)
    { 
        cout<<"Enter Element "<<j+1<<":";
        cin>>input;
        obj1 (i,j)=input; 
    }
  } 
}   

【问题讨论】:

  • template&lt;typename T&gt; using DS2DA = std::vector&lt;std::vector&lt;T&gt;&gt;;

标签: c++ class multidimensional-array dynamic jagged-arrays


【解决方案1】:

我很确定我没有抓住重点,但正如 Swordfish 在他的评论中所写的那样,包含 std::vectors 的 std::vector 应该可以解决问题。

如果您想要一个具有动态增长的宽度和高度限制的二维数组,请尝试以下代码:

template<class T>
class DynamicArray
{
public:
    DynamicArray()
        : rowCount(0),
        colCount(0)
    {}

    DynamicArray(size_t rowCount_, size_t colCount_)
        : rowCount(rowCount_),
        colCount(colCount_)
    {}

    const T& operator()(size_t row, size_t col) const
    {
        if (row >= rowCount || col >= colCount)
            throw std::out_of_range("Row or column index out of range in " __FUNCTION__);

        static const T empty;

        if (data.size() <= row)
            return empty;
        const auto& rowData = data[row];
        if (rowData.size() <= col)
            return empty;
        return rowData[col];
    }

    T& operator()(size_t row, size_t col)
    {
        if (row >= rowCount || col >= colCount)
            throw std::out_of_range("Row or column index out of range in " __FUNCTION__);

        if (data.size() <= row)
            data.resize(row + 1);
        auto& rowData = data[row];
        if (rowData.size() <= col)
            rowData.resize(col + 1);
        return rowData[col];
    }

public:
    std::vector<std::vector<T>> data;
    size_t rowCount, colCount;
};

数组开始时总是没有任何行或列,但有行/列限制(在默认构造函数中设置为 0)。

这两个 () 运算符的作用基本相同:检查行和列索引并返回相应的单元格。然而,当非常量 operator() 调整锯齿状数组的大小以容纳给定元素时,const operator() 只是返回对空(默认构造)项的引用。因此,您在遍历数组时不会不必要地构造所有缺失的项目。

也许一个以坐标对作为索引的 unordered_map 会根据用例为您提供更好的结果。您可以使用std::unordered_map&lt;std::pair&lt;int, int&gt;, T&gt; 声明它。一对整数应该会产生一个非常快的散列函数。对于一个非常稀疏的数组,这将是我的首选解决方案。

请注意,如果您不使用 Visual Studio,则可能需要调整(或省略)__FUNCTION__ 的使用。 (在 gcc 中,__FUNCTION__ 扩展为返回函数名称的函数,而 Visual Studio 将其扩展为包含当前函数名称的字符串)。

【讨论】:

    猜你喜欢
    • 2018-10-15
    • 2011-01-11
    • 2018-08-07
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2012-05-07
    相关资源
    最近更新 更多