Inserting Elements in Multidimensional Vector

Inserting elements in multidimensional Vector

Don't think of it as a multidimentional vector, think of it as a vector of vectors.

int n = 4;
std::vector<std::vector<int>> vec(n, std::vector<int>(n));

// looping through outer vector vec
for (int i = 0; i < n; i++) {
// looping through inner vector vec[i]
for (int j = 0; j < n; j++) {
(vec[i])[j] = i*n + j;
}
}

I included parentheses in (vec[i])[j] just for understanding.

Edit:

If you want to fill your vector via push_back, you can create a temporary vector in the inner loop, fill it, and then push_back it to your vector:

for (int i = 0; i < n; i++) {
std::vector<int> temp_vec;

for (int j = 0; j < n; j++) {
temp_vec.push_back(j);
}

vec.push_back(temp_vec);
}

However, push_back calls result in slower code, since not only you need to reallocate your vector all the time, but also you have to create a temporary and copy it.

Inserting values to a multidimensional-vector in C++

Since you declared the vector as size 9x9, yes that is a valid way of assigning values.

Otherwise you could declare the board as

vector<vector<string>> board;

Then fill it with

for (int i = 0; i < 9; ++i)
{
vector<string> row;
for (int j = 0; j < 9; ++j)
{
row.push_back(value); // where value is whatever you want
}
board.push_back(row);
}

But again, once the board is of size 9x9, you can simply assign a value at any cell for example

board[2][4] = "hello";

Working example

Inserting elements into 2D vector

To push on the vector that is an element of another vector, you simply do this

adjList[x].push_back();

How can I insert values in a 2D vector only using one of the dimensions?

You are adding values to an array of arrays.
(arr[i]) is actually an array itself. Every i represents a row, and every j represents a column. The first for loop is iterating through the rows and the second for loop is iterating through the columns (I'm sure you knew that though). arr[i].push_back(value) is actually adding value to arr[i][j] if you want to think of it that way. The first push_back adds value to arr[i][0], the second adds value to arr[i][1] and so on. If you had a 2D array of 0's for example, you would use arr[i][j]. The only reason you don't use it in this case is because if you reference arr[i][j] you will get an out of bounds exception since the index j doesn't exist yet (push_back creates it). I hope that makes sense. I thought an explanation made more sense than code since you already have the correct code and just needed an explanation.

Order of inserting elements into a 2D Vector in c++

vector.push_back(var) makes a copy of var and inserts it into the vector. If you use push_back() on an empty list, it copies the empty list into the vector. Changing values in the list after this does not affect the copy that was inserted into the vector. This is because you are passing an actual object to push_back(), not a pointer to an object.

In the third example, you take a step in the right direction, but you de-reference the list before you pass it in, so push_back() makes a copy of what is at that address.

A simple solution to the problem is to always set your values before you insert the list into the vector.

If you wish to be able to change the values after the list is inserted, use vect.at(i).push_back(val) to add a value to the list at i.
You could also make the vector contain pointers to other vectors, rather than the vectors themselves:

void fillVector(std::vector<std::vector<int> *> &vec) {
std::vector<int> *list1 = new std::vector<int>(); //Remember to allocate memory since we're using pointers now
list1->push_back(1);
list1->push_back(2);
vec.push_back(list1); // Copy the pointer that is list1 into vec

std::vector<int> *list2 = new std::vector<int>();
vec.push_back(list2); // Copy the pointer that is list2 into vec
list2->push_back(3);
list2->push_back(4);
return;
}

int main() {
std::vector<std::vector<int> *> vect; // Vector of pointers to vectors
fillVector(vect);

std::cout << "vect size: " << vect.size() << std::endl;

for(int i = 0; i < vect.size(); i++) {
std::cout << "vect in size: " << vect.at(i)->size() << std::endl;
}
}
std::vector<std::vector<int> *> vec = new; // Vector of pointers

Inserting an element in given positions (more than one) of a vector

Per the vector::insert() documentation on cppreference.com:

Causes reallocation if the new size() is greater than the old capacity(). If the new size() is greater than capacity(), all iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point remain valid. The past-the-end iterator is also invalidated.

Which means that, after your 1st call to insert(), your pos_col iterator is now invalid for subsequent calls to insert(), as it refers to an element before the insertion point.

Try using this instead:

auto pos_col = Col.begin();
for (const auto& elem: neigh) {
Col.insert(pos_col+elem,local_index);
pos_col = Col.begin();
}

Or simply:

Col.insert(Col.begin()+elem,local_index);

How to put characters from file into two-dimensional vector?

The reason for your problem is that you try to put a char into a std::vector of std vector. So you put a wrong type.

maze.at(row).push_back(token); would do it, but then no row exists. You also need to push_back and empty row, before you can write data to it.

That is your syntax error.

Then, your code could be drastically shortened by using C++ algorithms. See:


#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");

// This is a proxy to read a complete line with the extractor operator
struct CompleteLineAsVectorOfChar {
// Overloaded Extractor Operator
friend std::istream& operator>>(std::istream& is, CompleteLineAsVectorOfChar& cl) {
std::string s{}; cl.completeLine.clear(); std::getline(is, s);
std::copy(s.begin(), s.end(), std::back_inserter(cl.completeLine));
return is; }

operator std::vector<char>() const { return completeLine; } // Type cast operator for expected value
std::vector<char> completeLine{};
};

int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::vector<char>> maze { std::istream_iterator<CompleteLineAsVectorOfChar>(testDataFile), std::istream_iterator<CompleteLineAsVectorOfChar>() };

// Debug output: Copy all data to std::cout
std::for_each(maze.begin(), maze.end(), [](const std::vector<char> & l) {std::copy(l.begin(), l.end(), std::ostream_iterator<char>(std::cout, " ")); std::cout << '\n'; });

return 0;
}

But this is not the end. A std::vector<char>has no advantage over a string. You can work nearly have all the same functionality as a std::vector<char>. That is an improvement in design. The code would then look more like this:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");

int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };

// Debug output: Copy all data to std::cout
std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

return 0;
}

This is the by far more simpler solution. And it will serve your needs as well.

Please note: I used a istringstream for reading data, becuase I do not have a file on SO. But it is of cause the same as using any other stream (like an ifstream).

EDIT

The first solution read the source and put it directly into a std::vector<std::vector<char>>:

The 2nd solution put everything in the a std::vector<std::vector<std::string>> which is the most efficient solution. Also a std::string is nearly a std::vector<std::vector<char>>.

The OP requested a 3rd solution where we use the 2nd solution and then copy the std::vector<std::vector<std::string>> into a std::vector<std::vector<char>>.

Please see below


#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

std::istringstream testDataFile(
R"#(00000
11111
22222
33333
44444
)#");

int main()
{
// Read complete source file into maze, by simply defining the variable and using the range constructor
std::vector<std::string> maze{ std::istream_iterator<std::string>(testDataFile), std::istream_iterator<std::string>() };

// Debug output: Copy all data to std::cout
std::copy(maze.begin(), maze.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

// Edit: Copy into a std::vector<std::vector<char> -------------------------------------------------------
std::cout << "\n\n\nSolution 3:\n\n";

// Define the new variable with number of lines from the first maze
std::vector<std::vector<char>> mazeChar(maze.size());

// Copy the data from the original maze
std::transform(
maze.begin(), // Source
maze.end(),
mazeChar.begin(), // Destination
[](const std::string & s) {
std::vector<char>vc; // Copy columns
std::copy(s.begin(), s.end(), std::back_inserter(vc));
return vc;
}
);

// Debug Output
std::for_each(
mazeChar.begin(),
mazeChar.end(),
[](const std::vector<char> & vc) {
std::copy(vc.begin(), vc.end(), std::ostream_iterator<char>(std::cout));
std::cout << '\n';
}
);

return 0;
}

Hope this helps . . .

Input element by user into 2D vector c++

C++ is a strong type language, d is a vector of vector:

for(i=0; i<in; i++){ 
cout<<"ship"<<i+1<<":"<<' ';
vector<int> row;
for(j=0; j<in; j++){
cin>>temp;
row.push_back(temp);// I don't know how to push_back here!!
}
d.push_back(row);
}


Related Topics



Leave a reply



Submit