Динамический безопасный 2D Jagged Array в C ++ - PullRequest
0 голосов
/ 20 октября 2018

Как изменить класс массива Dynamic Safe 2D на класс динамических безопасных 2D-зубчатых массивов?Я прочитал статью, лучше и безопаснее использовать динамически безопасный или динамически безопасный 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; 
    }
  } 
}   

1 Ответ

0 голосов
/ 21 октября 2018

Я почти уверен, что упускаю из виду, но, как писал Swordfish в своем комментарии, std::vector, содержащий std::vector s, должен добиться цели.

Если вы хотите двумерный массив с ширинойи ограничение высоты, которое динамически увеличивается, попробуйте следующий код:

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).

Оба оператора () в основном делают одно и то же: проверяют индекс строки и столбца и возвращают соответствующую ячейку.Однако, в то время как неконстантный оператор () изменяет размер зубчатого массива для хранения данного элемента, const оператор () просто возвращает ссылку на пустой (созданный по умолчанию) элемент.Таким образом, вы не будете без необходимости создавать все недостающие элементы при итерации по массиву.

Возможно, unordered_map с парой координат в качестве индекса даст вам еще лучшие результаты в зависимости от варианта использования.Вы можете объявить это с помощью std::unordered_map<std::pair<int, int>, T>.Пара целых чисел должна привести к довольно быстрой функции хеширования.С очень разреженным массивом это было бы моим предпочтительным решением.

Помните, что использование __FUNCTION__ может потребоваться изменить (или опустить), если вы не используете Visual Studio.(в gcc __FUNCTION__ расширяется до функции, которая возвращает имя функции, в то время как Visual Studio расширяет его до строки, содержащей имя текущей функции).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...