【问题标题】:Declaring a vector<vector<pair<int, int>> with a specific size and inserting elements?声明具有特定大小并插入元素的 vector<vector<pair<int, int>>?
【发布时间】:2016-05-11 19:03:23
【问题描述】:

我想表示一个图形数据结构,我在 c++ stl 中使用对向量的向量。示例:

vector<vector<pair<int, int>>> G;

现在我可以了,G[u].push_back(make_pair(v, w));

问题:我需要为这个数据结构指定一个大小。如果我不尝试将元素推送到此数据结构时,我会遇到分段错误。如果我确实给出了这样的尺寸:

vector< vector<ii> > adj(10, std::vector<ii>(10));

现在的问题是前 10 对向量被初始化为零。如果我现在推回一个元素,它会被推到第 11 个位置。前 10 个为 0。我不想这样做。我想按我需要的顺序插入元素。一个 sn-p 让您了解我正在尝试做什么:

 for(int i=0;i<E-1;i++)
        {
            cin >> p >> q >> l;
            adj[p].push_back(ii(q, l));
            adj[q].push_back(ii(p, l));
        } 

上面的输出将是 10 个零,后跟推送的值。有什么办法可以解决这个问题?

【问题讨论】:

  • 或许想想std::vector&lt;ii&gt;(10)是什么意思。
  • 也许你得到一个分段错误,因为你没有为 G[u] 保留内存。

标签: c++ vector data-structures stl graph-theory


【解决方案1】:

不知何故,您自相矛盾:创建向量时,您可以在构造函数中传递元素的数量,也可以从空向量开始,然后将您想要的元素放入向量中。如果您从 10 号开始,然后再推 10 号,则有 20 号。他们的方法是使用

std::vector<T> vect(10);
for (size_t i=0;i<10;i++){
    vect[i] = whatever;
}

std::vector<T> vect;
for (size_t i=0;i<10;i++){
     vect.push_back(whatever);
}

也许您将向量的大小与其容量混淆了。您可以通过以下方式设置:

std::vector<T> vect;
vect.reserve(10);
for (size_t i=0;i<10;i++){
     vect.push_back(whatever);
}

对于您的向量向量,您必须确保在开始将元素推入其中之前,该索引处有一个向量:

std::vector<std::vector<T>> mat;
for (size_t i=0;i<10;i++){
    mat.push_back(std::vector<T>());
    for (size_t j=0;j<10;j++){
        mat[i].push_back(whatever);
    }
}

【讨论】:

    【解决方案2】:

    如果您事先知道您的数据结构大小,则可以使用适当的构造函数声明它:

    vector<vector<pair<int,int>>> G(10);
    

    当程序正在读取数据以填充该结构时,它可以检查输入的索引是否超出范围或相应地调整向量的大小。比如这个测试程序:

    #include <iostream>
    #include <vector>
    
    using std::vector;
    using std::pair;
    using std::cout;
    using std::cin;
    
    int main() {
    
        vector<vector<pair<int,int>>> G(5);
        //  insufficient initial size  ^^^
    
        int p, q, l;
        while ( cin >> p >> q >> l )
        {
            // resize the vector to avoid index out of bound
            int m = std::max(p, q) + 1;
            if ( m > G.size() )
                G.resize(m);
    
            G[p].push_back(std::make_pair(q, l));
            G[q].push_back(std::make_pair(p, l));
        } 
    
        for( int r = 0; r < G.size(); ++r )
        {
            for ( int c = 0; c < G[r].size(); ++c ) {
                cout << r << ", " << c << ": " << G[r][c].first << ' ' << G[r][c].second << '\n';
            }
        } 
    
        return 0;
    }
    

    输入如下:

    1 2 3
    4 5 6
    7 8 9
    8 7 6
    5 4 3
    2 1 0
    

    给出这个输出:

    1, 0: 2 3
    1, 1: 2 0
    2, 0: 1 3
    2, 1: 1 0
    4, 0: 5 6
    4, 1: 5 3
    5, 0: 4 6
    5, 1: 4 3
    7, 0: 8 9
    7, 1: 8 6
    8, 0: 7 9
    8, 1: 7 6
    

    【讨论】:

      【解决方案3】:

      分段错误是因为 u &gt;= G.size() 而不是 push_back()。

      你需要先将你G的大小调整为图形的顶点数,然后你可以回推,只要u &lt; G.size()

      更正后的代码应该是这样的:

      vector< vector<ii> > adj(10 /* number of vertexes in the graph */);
      for (int i=0; i < E-1; i++)
      {
          cin >> p >> q >> l;
          // make sure both p < adj.size() and q < adj.size()
          adj[p].push_back(ii(q, l));
          adj[q].push_back(ii(p, l));
      } 
      

      【讨论】:

      • 我想知道我的回答有什么问题?谁能给我这些反对票的理由?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      相关资源
      最近更新 更多