2017-02-03 4 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을 사용해야합니다

여기에 최소한의 생각이다. 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 = vector (3); // 벡터 안에 3 int '를 작성 if?왜 나는 그것을 단지 선언 할 수없고 필요할 때 그것을 덮칠 수 없습니까? –

+0

@RiccardoMarcaccioli 기꺼이 도와 드릴 수 있습니다. 귀하의 질문에 관해서, 당신은 둘 다 할 수 있습니다. 그러나 많은 전문 프로그래머가 내부에 선언하는 것이 더 낫다고 말합니다. 많은 변수가있는 매우 복잡한 함수가 있다고 상상해보십시오. * 모든 변수를 맨 위에 선언하고 * 다음에 * 사용하면 선언 된 이유를 기억하는 것이 어려울 것입니다. 변수를보고 "이게 또 뭐가 유용할까요?"라고 질문하면 모든 것을 스크롤하여 선언을 찾고 이해하고 다시 아래로 스크롤하여 "이 코드는 어떨까요?"하고 물어보십시오. 백업 등 –

+0

또한 변수가 맨 위에 선언 된 경우 * 전체 * 함수를 검색하여 변수가 사용 된 위치를 확인해야합니다. 누가 그 함수의 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

I * 전혀 * 귀하의 답변에 동의하지만, Riccardo의 경우 C++로 시작한 것 같습니다. 나는보다 단순하고 효율적인 해결책이 더 깨끗하고 효율적이지 않더라도 더 적합하다고 생각한다. –

+0

@AnthonyD. 글쎄, 우리는 불완전한 코드부터 디버깅 할 수 없다. 이것은 그들이 mcve를 게시하지 않는 한 내가 제공 할 최고입니다. – YSC

+0

답장을 보내 주셔서 감사합니다! 나는 벡터 벡터가 비싸고 제안하는 방법이 읽기와 속도 모두에서 더 쉽지만 int main()의 시작 부분에서 행렬의 크기를 선언한다고 이해한다. 얼마나 많은 행이 행렬에 포함될 지 모르겠다. 이제 3 행이 될 것임을 알았습니다. –