Initialize Vector Of Vectors in C++ - 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.

Related

C++, one block of memory vs multiple

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.

Accessing elements of a vector in a map of vectors

I want to create a map of vectors. I want the vector to be a private member variable however so when I need to increase the size of the vector for a particular key in the map it does it for all other keys in the map also(would that work?). This will be a map of vectors(of ints) where the keys are strings. My question is how to access a particular element in the vector to change is value in C++. Something along the lines of map_name['word'].[3] = 2 if i wanted to set the third value of the vector of "word" to 2.
enter image description here
enter image description here
Im still having trouble figuring out how to make it so the size of each vector for all the keys in the maps is modifiable so i can increase the size of each vector at any point along the program. This is b/c the vector size is unknown at runtime and iterating through each element in the map to change the vector size will take too long.
The pattern is recursive.
That is, when you do:
expression[key] = value;
your expression doesn't have to just be a variable name; it can be a more complex expression, such as map_name["word"].
So:
map_name["word"][3] = 2;
Regarding the first question, yes it is possible as mentioned in one of the comments, you can make your imaginary class to do that.
And in the second question, you'll have to access an element of a vector which is an element of a map like this:
map1["abc"][1] = 2
The '.' you added was unnecessary because you're accessing an element inside another element, just like a 2D array

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.

Redundant static data

This question applies to any type of static data. I'm only using int to keep the example simple.
I am reading in a large XML data file containing ints and storing them in a vector<int>. For the particular data I'm using, it's very common for the same value to be repeated consecutively many times.
<Node value="4" count="4000">
The count attribute means that the value is to be repeated x number of times:
for(int i = 0; i < 4000; i++)
vec.push_back(4);
It seems like a waste of memory to store the same value repeatedly when I already know that it is going to appear 4000 times in a row. However, I need to be able to index into the vector at any point.
For larger data objects, I know that I can just store a pointers but that would still involve storing 4000 identical pointers in the example above.
Is there any type of strategy to deal with an issue like this?
Use two vectors. The first vector contains the indices, the second one the actual values.
Fill in the indices vector such that the value for all indices between indices[i-1] and indices [i] is in values[i].
Then use binary search on the indices array to locate the position in the values array. Binary search is very efficient (O(log n)), and you will only use a fraction of the memory compared to the original approach.
If you assume the following data:
4000 ints with value "4"
followed by 200 ints with value "3"
followed by 5000 ints with value "10"
You would create an index vector and value vector and fill it like this:
indices = {4000, 4200, 9200}; // indices[i+1] = indices [i] + new_count or 0
values = {4,3,10};
As suggested in the other answers, you should probably wrap this in an operator[].
I would suggest to write a specific class instead of using vector.
Your class should just hold the number of times an item occurs in a list and compute the index in a smart way so you can easily retrieve an element based on the index.
Try to wrap your data into some objects with vector-like interface (operator[] and so on), so you can hide implementation detail (that is you are not actually storing 4000 numbers) yet provide similar interface.

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