首页 > 解决方案 > C++ 中的动态安全二维交错数组

问题描述

我应该如何将 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; 
    }
  } 
}   

标签: c++classmultidimensional-arraydynamicjagged-arrays

解决方案


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

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

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<std::pair<int, int>, T>. 一对整数应该会产生一个非常快的散列函数。对于非常稀疏的数组,这将是我的首选解决方案。

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


推荐阅读