在 C++ 中动态调整和填充向量的向量
Dynamically resizing and filling a vector of vectors in C++
我有一个包含未知行数和 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++ 新手。)
我强烈建议在内部对数据进行线性化;向量的向量使用起来很昂贵(例如,当外部向量重新定位其内存时)并且读取和编写使用它们的代码很痛苦。
这是一个最小的想法:
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;
};
就像你说的,你应该使用push_back
。不要使用 resize
。 push_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(或 class),你可以调用 EdgeList
。然而,这不是必需的。
编辑:你可以找到更有效和更好的方法来做同样的事情(就像下面的 YSC 所做的那样),但是如果你是一个小程序的初学者并且你真的不介意降低效率那么这个应该易于编程并且足够好。
我有一个包含未知行数和 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++ 新手。)
我强烈建议在内部对数据进行线性化;向量的向量使用起来很昂贵(例如,当外部向量重新定位其内存时)并且读取和编写使用它们的代码很痛苦。
这是一个最小的想法:
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;
};
就像你说的,你应该使用push_back
。不要使用 resize
。 push_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(或 class),你可以调用 EdgeList
。然而,这不是必需的。
编辑:你可以找到更有效和更好的方法来做同样的事情(就像下面的 YSC 所做的那样),但是如果你是一个小程序的初学者并且你真的不介意降低效率那么这个应该易于编程并且足够好。