saru
saru

Reputation: 255

How can I push_back data in a 2d vector of type int

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

Answers (9)

Vivek Verma
Vivek Verma

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

tinku kalluri
tinku kalluri

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

allam taju sarof
allam taju sarof

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

Umang Kalra
Umang Kalra

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

SingerOfTheFall
SingerOfTheFall

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

Vlad from Moscow
Vlad from Moscow

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

A. Monti
A. Monti

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 :

Resize the vector prior to inserting elements

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.

Use a flat 2D array

If you want to store a 2D array, this is not the optimal solution, because :

  1. Your array data is spread across N different dynamically allocated buffers (for N lines)
  2. Your array can have a different number of columns per line (because nothing enforces that 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

user3853544
user3853544

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

Cory Kramer
Cory Kramer

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

Related Questions