在C ++中动态调整大小和填充向量向量

时间:2017-02-03 16:25:16

标签: c++ vector resize push-back

我有一个包含未知行数和3列的向量。矢量应该如下构造:进行统计测试,如果它超过阈值,则矢量应该存储关于它的信息。 我在做的是:

vector< vector < int > > validated_edge_list;
validated_edge_list.resize(1);
validated_edge_list.at(1).resize(3);

for(int i = 0; i < e ; i++)
{
    p = gsl_cdf_hypergeometric_P(edge_list[i][2],
                                 k_vec[edge_list[i][1]],
                                 M-k_vec[edge_list[i][1]],
                                 N_vec[edge_list[i][0]]); // n2_matrix[i][j] = M-k_matrix[i][j]

    if (p <= bonferroni_lvl)
    {
        validated_edge_list[c][0] = edge_list[i][0];
        validated_edge_list[c][1] = edge_list[i][1];
        validated_edge_list[c][2] = edge_list[i][2];
        c = c + 1;
        validated_edge_list.resize(c+1);
        validated_edge_list.at(c+1).resize(3);
    }
}

正如您所看到的,我每次都手动添加新的原始数据。它给了我以下错误:

terminate called after throwing an instance of 'std::out_of_range'
what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
Aborted (core dumped)

我可以假设我做错了,我也认为我应该使用push_back选项,但我不知道如何。

我该如何解决这个问题? (我是C ++的新手。)

2 个答案:

答案 0 :(得分:0)

我强烈建议您在内部线性化数据;向量向量的工作成本很高(例如,当外部向量重新定位其内存时),读取和编写使用它们的代码很痛苦。

这是一个很小的想法:

template<class T, std::size_t width>
struct Matrix
{
    Matrix(std::size_t height) { _data.reserve(width*height); }
    const T& operator()(std::size_t i, std::size_t j) const { return _data[i*width+j]; }
          T& operator()(std::size_t i, std::size_t j)       { return _data[i*width+j]; }

private:
    std::vector<T> _data;
};

Usage example on coliru

答案 1 :(得分:0)

就像你说的那样,你应该使用push_back。不要使用resizepush_back用于向向量添加元素并处理所有内容。但是,resize只会增加或减少矢量的容量。

可能的解决方案:(我还没有测试过,但这应该会给你一般的想法)

vector< vector < int > > validated_edge_list;

for(int i = 0; i < e ; i++)
{ 
    p = gsl_cdf_hypergeometric_P (edge_list[i][2],k_vec[edge_list[i][1]],M-k_vec[edge_list[i][1]],N_vec[edge_list[i][0]]); // n2_matrix[i][j] = M-k_matrix[i][j]
    if (p <= bonferroni_lvl)
    {
        vector<int> single_edge_list = vector<int>(3); // Create a vector a 3 int's
        single_edge_list[0] = edge_list[i][0] ; // Fill the vector.
        single_edge_list[1] = edge_list[i][1] ; // Fill the vector.
        single_edge_list[2] = edge_list[i][2] ; // Fill the vector.

        validated_edge_list.push_back(single_edge_list); // Add it to validated_edge_list.
        c++; // You don't really need this anymore
    }

}

请注意,由于validated_edge_list内的向量都有3的长度,你不需要使用向量向量,你可以只使用structure(或类)可以致电EdgeList。但是,没有必要。

编辑:你可以找到更有效和更好的方法来做同样的事情(比如YSC在下面做过),但是如果你是一个初学者从事一个小程序并且你真的不介意降低效率那么这应该是易于编程且足够好。