Reputation: 255
I have a vector and want to store int data in to it at run time can I store the data in a 2D vector in this manner ?
std::vector<std::vector <int>> normal:
for(i=0;i<10;i++){
for(j=0;j<20;j++){
normal[i].push_back(j);
}
}
Upvotes: 15
Views: 107862
Reputation: 1
Let's understand with a simple greedy problem. Stock buy and sell:
One approach is using temporary vector i.e.
vector<vector<int> > stockBuySell(vector<int> A, int n){
vector<vector<int>> v;
vector<int> temp;
for(int i=1;i<n;i++)
{
if(A[i]>A[i-1])
{
temp.push_back(i-1);
temp.push_back(i);
v.push_back(temp);
temp.clear();
}
}
return v;
}
Another approach is :
vector<vector<int> > stockBuySell(vector<int> A, int n){
vector<vector<int>> v;
for(int i=1;i<n;i++)
{
if(A[i]>A[i-1])
v.push_back({i-1,i});
}
return v;
}
So, If we have to push some small size vectors like 2 or 3 in 2-d vector then this way we can directly push in a 2-d vector i.e. vector_name.push_back({1,2,3}); likewise using {} brackets. Hence we don't have to use any extra temporary vector.
Upvotes: 0
Reputation: 63
create a temporary vector push elements into this temporary vector and then push this temporary vector(v2 in my code) into a 2d vector(v1 in my code).
#include <iostream>
#include <bits/stdc++.h>
#include<algorithm>
using namespace std;
int main()
{
vector<vector<int>> v1;
vector<int> v2;
v2.push_back(1);
v2.push_back(2);
v2.push_back(13);
v2.push_back(14);
v2.push_back(15);
v1.push_back(v2);
//i pushed v2 into v1
int j=0;
for(int i=0 ; i<5 ;i++)
{
cout<<v1[0][i]<<"\t";
}
}
Upvotes: 3
Reputation: 1
I think it is possible to use such pointer to the sub vectors. But it still need to be declared with an empty vector before we can push_back() the sub vector.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main () {
vector<vector<ll>> normal;
for (ll i=0; i<10; i++) {
normal.push_back({}); //init empty sub vector
for (ll j=0; j<20; j++) {
vector<ll>& temp = normal[i]; //point the sub vector
temp.push_back(j); //pus_back the sub vector
}
}
for (ll i=0; i<10; i++) {
for (ll j=0; j<20; j++) {
printf("%lld ", normal[i][j]);
}printf("\n");
}
return 0;
}
Upvotes: 0
Reputation: 1
Allocate n empty vectors, that is, empty vector for each index. Then push_back() can be applied.
int main()
{
int n = 10;
std::vector<std::vector<int>> normal;
normal.resize(n); //Allocating 'n' empty vectors
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 20; j++)
{
normal[i].push_back(j);
}
}
return 0;
}
Upvotes: 0
Reputation: 29966
Yes, but you also need to push each of the sub-vectors:
std::vector<std::vector<int>> normal;
for(int i=0; i<10; i++)
{
normal.push_back(std::vector<int>());
for(int j=0; j<20; j++)
{
normal[i].push_back(j);
}
}
Upvotes: 27
Reputation: 311038
Here is one more approach.
#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
int main()
{
std::vector<std::vector <int> > normal;
normal.resize( 10, std::vector<int>( 20 ) );
for ( auto &v : normal ) std::iota( v.begin(), v.end(), 0 );
for ( const auto &v : normal )
{
for ( int x : v ) std::cout << std::setw( 2 ) << x << ' ';
std::cout << std::endl;
}
}
The program output is
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
You can write a corresponding function
#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
template <typename T>
T & init_2d( T &container, size_t m, size_t n )
{
container.resize( m, typename T::value_type( n ) );
for ( auto &item : container ) std::iota( item.begin(), item.end(), 0 );
return container;
}
int main()
{
std::vector<std::vector<int>> v;
for ( const auto &v : init_2d( v, 10, 20 ) )
{
for ( int x : v ) std::cout << std::setw( 2 ) << x << ' ';
std::cout << std::endl;
}
}
Upvotes: 0
Reputation: 491
You are manipulating a vector of vectors.
As such, when declaring normal
it is empty and does not contain any element.
You can either :
std::vector<std::vector<int> > normal;
normal.resize(20);
for (size_t i = 0; i < normal.size(); ++i)
{
for (size_t j = 0; j < 20; ++j)
normal[i].push_back(j);
}
This may be slightly more efficient than pushing an empty vector at each step as proposed in other answers.
If you want to store a 2D array, this is not the optimal solution, because :
normal[i].size() == normal[j].size()
Instead, you can use a vector of size N * M
(where N
is the number of lines and M
the number of columns), and access an element at line i
and columns j
using the index i + j * N
:
size_t N = 20;
size_t M = 20;
std::vector<int> normal;
normal.resize(N * M);
for (size_t i = 0; i < N; ++i)
for (size_t j = 0; j < M; ++j)
normal[i + j * N] = j;
Upvotes: 8
Reputation: 583
You have a vector of vectors.
normal[i] Does not exist because you have not created it.
std::vector<std::vector <int> > normal:
for(i=0;i<10;i++){
normal.emplace_back();
for(j=0;j<20;j++){
normal.back().push_back(j);
}
}
for(i=0;i<10;i++){
for(j=0;j<20;j++){
std::cout << normal[i][j] << " ";
}
std::cout << std::endl;
}
Upvotes: 1
Reputation: 117906
You cannot directly assign to [i]
without allocating the outer and inner vectors first. One solution to this would be to create the inner vectors inside your for loop, then once those are populated, push_back to the outer vector.
std::vector<std::vector<int>> normal;
for(i=0;i<10;i++)
{
std::vector<int> temp;
for(j=0;j<20;j++)
{
temp.push_back(j);
}
normal.push_back(temp);
}
Upvotes: 1