如何在一个类型为int的二维向量中使用push_back函数添加数据?

15
我有一个向量并想在运行时将int数据存储到其中,我可以用这种方式将数据存储在2D向量中吗?

我有一个向量,并且想在运行时将int数据存储在其中。我能否以这种方式将数据存储在2D向量中?

std::vector<std::vector <int>> normal:
    for(i=0;i<10;i++){
        for(j=0;j<20;j++){
            normal[i].push_back(j);
    }
}

2
你没有一个“2D向量”,你有一个int类型的向量的向量。如果你记得这一点,就很容易看出你需要做什么:在外部循环的每次迭代中推入一个向量。 - Some programmer dude
如果大小在声明时已知,您可以将其传递给构造函数或调用resize。 - slawekwin
谢谢您解释,我有点困惑。 - saru
9个回答

27

是的,但你还需要推每个子向量:

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

8
您正在操作一个向量的向量。因此,在声明 normal 时,它是空的,不包含任何元素。
您可以选择:

在插入元素之前调整向量大小

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

这种方法可能比其他答案中提出的在每个步骤中推送一个空向量稍微更有效。

使用平面2D数组

如果您想要存储一个2D数组,那么这不是最优解决方案,因为:

  1. 数组数据分布在N个不同的动态分配缓冲区中(对于N行)
  2. 数组可以具有每行不同的列数(因为没有强制执行normal[i].size() == normal[j].size()

相反,您可以使用大小为N * M的向量(其中N是行数,M是列数),并使用索引i + j * N访问位于第i行和第j列的元素:

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;

我认为你的意思是 normal.resize(10),它代表列长度。 - Shailesh

3
创建一个临时向量,将元素推入该临时向量,然后将此临时向量(我的代码中为v2)推入一个二维向量(我的代码中为v1)。
#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";
    }
  }

1

如果您没有先分配外部和内部向量,则无法直接分配给[i]。解决此问题的一种方法是在for循环内创建内部向量,然后在填充了这些向量后,将其push_back到外部向量中。

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

1

你有一个向量的向量。

normal[i] 不存在,因为你还没有创建它。

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

0

我认为可以使用这样的指针指向子向量。但是在我们可以push_back()子向量之前,仍然需要声明一个空向量。

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

0

让我们通过一个简单的贪心问题来理解。 股票买卖:

一种方法是使用临时向量,即。

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

另一种方法是:
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;
}

如果我们需要将一些小尺寸的向量(如2或3)推入二维向量中,那么我们可以直接使用vector_name.push_back({1,2,3})这种方式将其推入二维向量中,同样使用{}括号。因此,我们不需要使用任何额外的临时向量。


0

分配n个空向量,即每个索引的空向量。然后可以使用push_back()方法。

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

请问您能否在答案中说明您的回答与其他人的主要区别是什么? - Giulio Caccin

0

这里还有一种方法。

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

程序输出为:

 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 

你可以编写一个相应的函数。
#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;
    }

}   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接