2017-02-03 5 views
-2

私は、行数と列数が不明なベクトルを持っています。ベクタは以下のように構築されるべきである。統計的テストが行​​われる。閾値に合格すると、ベクタはそれに関する情報を格納する。私がやっている何 は次のとおりです。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) 

私は私が何か間違ったことをやっていると私はまた、私は一backオプションを使用する必要があると思いますが、私は方法がわからないと仮定することができます。

どうすればこの問題を解決できますか? (私はC++の新機能です)

+0

あなたの質問に[mcve]を含めるように[編集]してください。 – YSC

+0

'c = c + 1;'は 'C++;'に短縮することができます 'resize()'と 'at()'の後ろに '+ 1'を2つ移動することもできます。 –

答えて

0

:ここ

は、最小限のアイデアです。 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(またはクラス)を使用してEdgeListと呼ぶことができます。しかし、それは必要ではありません。

EDIT:同じことをするのがより効率的で良い方法を見つけることができます(YSCのように)。しかし、小さなプログラムで作業している初心者で、プログラムしやすく、十分に良い。

+0

ありがとう!!一つの質問:私は本当に 'ベクトルを入れる必要がありますか? single_edge_list =ベクトル(3); // if内部に3 int's'のベクトルを作成しますか?なぜ私はそれをただのものと宣言することができず、必要なときにそれを覆すことができないのですか? –

+0

@RiccardoMarcaccioli私は助けることができました。あなたの質問については、両方を行うことができます。しかし、多くのプロのプログラマーは、内部を宣言する方が良いことを伝えます。多くの変数を持つ、本当に複雑な関数があるとします。 *すべての*変数を先頭に宣言し、*以下でそれらを使用すると、宣言された理由が何であるかを覚えにくくなります。あなたは変数を見て、 "これは何の役に立つでしょう?"と尋ねると、スクロールして宣言を見つけ、それを理解し、スクロールバックして自分自身に質問します。バックアップなど –

+0

また、変数が先頭に宣言されている場合は、* whole *関数を検索して、その変数がどこで使用されているかを確認する必要があります。だから、関数の300行の中でおそらくあなたが少し「i ++」を見なかったのは分かっています...あなたができるだけ遅く宣言すれば、その変数がその前に使われていないことを100%確信しています宣言された。したがって、コードの理解とデバッグにかかる​​時間が大幅に短縮されます。 (PS、あなたが他の人のコードを読んでいて、彼らが一番上の変数を宣言していると想像してください!!あなたのワークメイトがあなたの*コードについてこれを考えるのは嫌ですか?) –

0

データを内部的に線形化することを強くお勧めします。ベクトルのベクトルは(外部ベクトルがそのメモリを再配置するときに)扱うのに費用がかかり、それらを使用するコードを読み書きするのは苦労します。あなたはpush_backを使用する必要があり、言ったように

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つの列になるようになっています –

関連する問題