2017-02-03 117 views
-2

我有一个矢量,它具有未知数量的行和3列。向量的构造如下:进行统计测试,如果它通过了阈值,则向量应该存储关于它的信息。 什么我做的是:动态调整大小并在C++中填充矢量矢量

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++。)

+0

请[编辑]你的问题,包括[mcve]。 – YSC

+0

'c = c + 1;'可以缩写为'C++;'也可以通过在'resize()'和'at()'后面移动两个'+ 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下面做的),但如果你是一个初学者在一个小程序上工作,而你并不介意降低效率,那么这应该很容易编程和足够好。

+0

谢谢!一个问题:我真的需要把'vector single_edge_list = vector (3); //在if中创建一个向量3 int's'?为什么我不能在必要时宣布它只是过分强调它? –

+0

@RiccardoMarcaccioli很高兴能帮到你。关于你的问题,你可以同时做。但是,许多专业程序员会告诉你,声明内部更好。想象一下,你有一个非常复杂的函数,有很多变量。如果你在顶部声明* all *变量,然后*在下面使用它们,那么你很难记住它们为什么被声明的原因。你看到一个变量,并问“这又有什么用?”,然后你必须一直向上滚动,找到声明,理解它,向下滚动并问自己,“这个怎么样?”,去备份等 –

+0

另外,如果变量是在顶部声明的,则必须搜索* whole *函数以查看该变量的使用位置。谁知道,也许在这个函数的300行中,你没有看到一个'i ++'......然而,如果你尽可能晚的声明,你可以100%确定变量在之前没有被使用过被宣布。因此,理解和调试代码需要更少的时间。 (PS,想象一下,如果你正在阅读别人的代码,并且他们在顶部一直声明他们的变量!!你不想让你的同事们考虑这个*你的代码,是吗?) –

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

+0

我*完全*同意你的答案,但在Riccardo的情况下,他似乎只是从C++开始。我认为一个更简单的工作解决方案会更合适,即使它不那么干净,也不够高效。 –

+0

@AnthonyD。那么,我们不能调试他们的代码,因为它不完整。这是我给他们的最好的,除非他们发布了一个mcve。 – YSC

+0

感谢您的回复!我明白,向量向量是昂贵的,并且你提出的方法在读取和速度上都更容易,但是你在int main()的开头声明了矩阵的大小。我不知道矩阵中会包含多少行,我现在只需要有3列 –