Как объявить 2D динамический c массив в C ++ - PullRequest
0 голосов
/ 19 апреля 2020

Как объявить двумерный массив, в котором строки являются динамическими c, но длина строк фиксирована? Есть ли способ сделать это без длины строки и строки являются Dynami c?

PS Я не могу использовать контейнеры STL или строку класса.

Ответы [ 4 ]

4 голосов
/ 19 апреля 2020

Для этого вы можете использовать std::vector и std::array.

std::vector - это динамический массив c-длины.

std::array - это массив фиксированной длины, используемый как

array<int, 20> arr;
arr[10] = 42;
array<int, 20> anotherArr = arr; // copied here, as opposed to C arrays

int oldStyleArr[20];
oldStyleArr[10] = 42;
// int newStyleArr[20] = oldStyleArr; // error here

. Это удобная оболочка для массива C -стилей, которая обеспечивает семантику значений и различные методы удобства, такие как * 1016. *.

Таким образом, вы можете создать array<vector<int>, 20> для массива из 20 динамических c векторов int с или vector<array<int, 20>> для динамического c вектора массивов фиксированной длины.

UPD: std::array работает только с границами массива, известными во время компиляции. Если границы вашего массива известны только во время выполнения, вы все равно можете использовать конструктор std::vector по размеру и (необязательно) элемент:

int rowCount, columnCount;
cin >> rowCount >> columnCount;
using Row = vector<int>;

// create `vector` of `rowCount` rows,
// where each row is `vector` of `columnCount` ints
vector<Row> arr2d(rowCount, Row(columnCount));

Однако это не самое эффективное решение, поскольку каждая строка выделяется раздельно. Вы можете решить эту проблему с помощью небольшой обертки над одномерным vector:

template<class T>
class Vector2D {
public:
  Vector2D(int rows, int cols)
    : data(rows*cols)
    , rows(rows)
    , cols(cols) {}

  int rowCount() const { return rows; }
  int columnCount() const { return cols; }

  T&       get(int r, int c)       { return data[r*cols + c]; }
  T const& get(int r, int c) const { return data[r*cols + c]; }

  void addRow() {
    data.resize(cols*(rows + 1));
  }

// ...

private:
  vector<T> data;
  int rows;
  int cols;
};
0 голосов
/ 19 апреля 2020

Вероятно, вы ищете: std::vector<std::array<int, 20>> arr;

Однако, если контейнеры STL не являются опцией, вам может потребоваться реализовать контейнер самостоятельно. Связанный список, вероятно, проще всего реализовать.

0 голосов
/ 19 апреля 2020

Просто объявите одномерный массив и рассчитайте индекс самостоятельно, например, как компилятор обращается к многомерному массиву. Каждая строка содержит width элементов, поэтому элемент [x][y] будет иметь индекс x*width + y

template<typename T>
class twoD
{
    T* data;
    int width;
    int height;

    twoD(int width, int height) : width(width), height(height)
    {
        data = new T[width*height];
    }

    T& get(int x, int y)
    {
        return data[x*width + y];
    }

    ~twoD()
    {
        delete[] data;
    }
}
0 голосов
/ 19 апреля 2020

Вы можете использовать std::vector для динамических c массивов диапазона. Вы бы хотели создать экземпляр массива для достижения этой цели.

...