C++, one block of memory vs multiple - c++

I am new to C++ and wanted to create a class for matrix and found two methods:
allocating one block of memory (which is faster as I read)
allocating multiple blocks (one for each line which is slower)
But what is better?
on the one hand I can use the second like mat[i][j] which doesn't work with the first method.
and I need to write a function that multiplies matrixes and I'm afraid that the first method will make things really hard when trying to access members

Where did you read that? 2-dimensional matrix can be represented both as a 1-dimensional array or 2-dimensional array. It's just a matter of references with 2 index. So for an element of having index row and col you can get its 1-dimensional index like this: row * matrix_width + col. So there's no impact on the speed besides calculating this index formula.

Related

How to change the xyz order when using a flattened 3D array

I'm using a flattened 3d array for my program, and from everything I've read, the way to access it is: array[x + width * (y + depth * z)]
This is the equivalent of array[x][y][z]
Unfortunately in my code I need to use array[x][z][y] Does anyone know how to change the flattened formula from xyz to xzy?
As long as you stay consistent in accessing the array, you can access it however you like. A "flattened" 3D array is just a normal array now, and the indices has absolutely no meaning for the system. The only meaning is what you assign to them in your mind.
Therefore, it is perfectly OK to imagine the array to be - as you put it - an XZY array instead of an XYZ array, or any other permutation of the indices. The general formula is (when you are imagining the array to be a flattened 3D array):
FlatIndex(1st, 2nd, 3rd) = 1st * PlaneSize + 2nd * RowSize + 3rd;
where RowSize is obviously the number of elements in a row (i.e. the number of elements in the 3rd dimension) and PlaneSize is the number of elements in a plane, or the number of elements in a row times the number of rows there is.
Deriving the above formula is simple: if you think about how the elements are put beside each other, you will see that when you increment the 3rd index by 1, you increase its "address" by 1 as well (address means where it is in the 1D array) hence the fact that the 3rd index has a coefficient of 1. When you increase the 2nd index by 1, you are effectively going to the next row, and your address in increased by a row's worth of elements at once. In other words, an increment of 1 for the 2nd index is the same as an increment equal to the size of a row for the 3rd index, therefore the 2nd index has a coefficient of RowSize. The same goes for the 1st index.
If we had any number of indices (i.e. a flattened N-dimensional array,) the reasoning would have been the same.
But this is all imaginary. You can devise any "mapping" function between the three indices used in a 3D array and the single index used in a normal 1D array (with some restrictions; e.g. it must cover all your domain, and it must be reversible.) The formula everybody uses though is a pretty good one: it's fast to compute, it's 1-to-1 which means it uses all the entries in the 1D array and leaves no holes (i.e. wastes no memory,) etc.
As long as you are consistent in use of your mapping function (in all its aspects, including the order of indices) everywhere you access the same array, you'll be fine.

Initialize Vector Of Vectors in C++

I am trying to use vector of vectors in C++ as a 2D array. I have to read input into it from the user. The number of rows and columns are also to be input by the user.
Supose I read m * n matrix,
I tried to allocate space using reserve(m*n) but is also giving error in building.
This is a general problem I face, I mean even in strings wherein you read char by char, how do you provide it space so you can access index i (I know it can be done using .resize(given_size)) but in situations where it is not known how many chars a user will input, this can't be done (this can be circumvented using + operator but still it is not a direct solution).
So, My primary question is how initialize the vector of vectors (not putting in values but just allocating required space, rows and columns) so that I can access [i][j] to read an value to it ?
I know that matrix can be built using vector of vectors like here but I want to first declare a vector of vectors and then take input of rows and columns to allocate space so that I can access [i][j] to input elements.
std::vector<std::vector<T>> my_vec(m, std::vector<T>(n))
Be careful that Ts default constructor is called for each of m * n members of the matrix.

Two Dimensional Vectors in C++

Hey I was curious about creating a 2 dimensional vector of chars so I know it's a vector inside a vector and I'd like to initialize all values to ','.
So i know this much I believe
vector<vector<char>> spaceStation();
I'm guessing the columns and rows go in the parenthesis but I'm not exactly sure.
Thanks!
If it is going to be a nxn or nxm 2D matrix that you are looking for, where n and m can be determined before the creation of the matrix (even if it at run time) then vector of vectors may not be the most efficient way to go about it. Internally the way vector grows is by allocating a bigger memory if the current allocated space gets filled up and moving all the existing data to the new location. Similarly inserting a new first row would require all the vectors to move down which would in turn result in copying all the other vectors and its elements down.
If you know n,m, even if it is at run time you could allocated a big block of memory using a single vector (of size n^2 or nxm) and access elements logically as a vector (a[i][j] would be vector[i*n + j]) thus efficiently managing a single memory block.

What's the best way to read a matrix of unknown columns from standard input?

I know only the number of rows r in a matrix.
How do I read it into a multi-dimensional array arr[MAX][MAX]?
I thought of reading all the elements into a single array, count the no. of elements and then adding them to arr in groups of count/r. Is there a simpler way?
You could use the fact that everything may as well go into contiguous memory so just keep pushing it at the end of std::vector<double>. At the end you know its length, and given that you know r, you now also know the number of columns.
If you really have nothing but the number of rows and a list of data values, just read the whole thing into a vector, and then divide the size of the vector by the number of rows to get the number of columns. You should, however, also know whether the data is stored row-wise or column-wise. On this depends how to index the vector (I would keep the data in the vector and access it through index calculation, most probably encapsulated in a nice little class).

Efficiant multidimensional data storage in C++

I'm trying to write a C++ program that needs to store and adjust data in a 3D array. The size is given by the user and doesn't change throughout the run, and I don't need to perform any complicated matrix operations on it. I just need it to be optimized to set and get from given 3D coordinates (I do quite some iterations over all the members, and it's a big array). What's the best way to go about defining that array? Vector of vector of vector? Arrays of vectors? CvMat/IplImage with multi channels? Should I even keep it as 3D or just turn it into one very long interleaved vector and calculate indexes accordingly?
Thanks!
I would go with your last option, a single large array with transformed indices. If all you want to do is read and write known indices, this is probably the most efficient structure, both in terms of storage and speed. You can also wrap this in a class and overload operator () to make it easy to access 3D coordinates, for eg. you could write a(1,2,3) = 10; and the overloaded operator could take care transforming the 3D coordinates into a linear index. Iterating over such an array would also be quite simple since there's only one dimension.
It depends on what you mean by efficient, but have you looked at KD Trees?