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

9

15

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);
    }
}
Pregnable answered 15/2, 2017 at 12:22 Comment(3)
You don't have a "2d vector", you have a vector of vectors of int. If you remember that it's easy to see what you need to do: Push back a vector for each iteration of the outer loop.Foremost
or if size is known at declaration time you could pass it to the constructor or call resizeSelma
Thank you for explaining it i was little bit confused about itPregnable
D
27

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);    
    }
}
Divisive answered 15/2, 2017 at 12:25 Comment(0)
E
8

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;
Exclusion answered 15/2, 2017 at 12:32 Comment(1)
I think you mean to say normal.resize(10) which represents column lengthEditheditha
A
3

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";
    }
  }
Aloysia answered 1/6, 2021 at 7:26 Comment(0)
R
1

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);
}
Ravenous answered 15/2, 2017 at 12:25 Comment(0)
D
1

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;
}
Dibasic answered 15/2, 2017 at 12:27 Comment(0)
W
0

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;
    }

}   
Waist answered 15/2, 2017 at 14:12 Comment(0)
F
0

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;
}
Funky answered 31/7, 2019 at 11:11 Comment(1)
can you please state on the answer what is the main difference between your answer and others people?Lindell
M
0

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;
}
Misuse answered 9/5, 2021 at 23:0 Comment(0)
B
0

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.

Blastula answered 3/10, 2022 at 7:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.