Reputation: 49
How to declare a 2D array in which the rows are dynamic but the rows length are fixed? Is there any way to do it without both row and rows length are dynamic?
P.S. I can't use STL containers or class string.
Upvotes: 0
Views: 317
Reputation: 41754
Just declare a 1D array and calculate the index yourself like how compilers generate accesses to a multidimensional array. Each row has width
items, so the [x][y]
element will have the index x*width + y
template<typename T>
class twoD
{
const int width;
const int height;
T* data;
twoD(int w, int h) : width(w), height(h)
{
data = new T[width*height];
}
~twoD()
{
delete[] data;
}
T& at(int x, int y)
{
return data[x*width + y];
}
T const& at(int x, int y) const
{
return data[x*width + y];
}
}
twoD myArray(4, 8);
myArray.at(2, 3) = 5;
myArray.at(4, 5) = 6 - myArray.at(2, 3);
The same method can be used to access multidimensional arrays in any degree
Upvotes: 0
Reputation: 1365
You can use std::vector
and std::array
for this.
std::vector
is a dynamic-length array.
std::array
is a fixed-length array, used as
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
It is a convenient wrapper over the C-style array, and it provides value semantics and various conveniece methods like size()
.
So you can create array<vector<int>, 20>
for an array of 20 dynamic vectors of int
s or vector<array<int, 20>>
for a dynamic vector of fixed-length arrays.
UPD: std::array
works only with array bounds known at compile-time. If your array bounds are known only at runtime, you still can use std::vector
's constructor from size and (optional) element:
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));
However, that's not the most efficient solution because each row is allocated separately. You can solve this with a little wrapper over one-dimensional 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;
};
Upvotes: 4
Reputation: 31
What you are looking for is probably: std::vector<std::array<int, 20>> arr;
However, if STL containers are not an option you might need to implement the container yourself. A linked list is probably the easiest to implement.
Upvotes: 0
Reputation: 147
You can use std::vector
for dynamic range arrays. You would want to instantiate a vector of arrays to achieve this.
Upvotes: 0